C++的继承关于向上类型转换

C++的继承关于向上类型转换

分类:C++

对于一个类比如马类来说可以分为很多比如千里马等等的对象,比如千里马有时候也可以作为一个类假如说是千里马类下的黑马,它是千里马的一个对象,所以它也是马,所以说它也是马的对象,这就是派生类的对象也是基类的对象,但是反过来不能说马是黑马的对象,所以计算机科学中所有都是在描述现实生活中的实物之间的关系(哈哈 我又感慨了一下)(顺便再说一句在代码中可以通过强制类型转换使向下类型转换,但是这是不安全的)

下来看几个例子

enum note{middleC,Csharp,Cflat};class Instrument{public:void play(note )const{cout<<"Instrument Play\n";}};class Wind:public Instrument{    void play(note )const    {            cout<<"Wind Play\n";    } };void tune(Instrument &i){i.play(middleC);}void main(){Wind flute;//Wind继承了Instrucment也是Instrument的对象tune (flute);//upcast 向上类型转换 这里转换之后就会认为是基类的对象当然只能调用基类的函数,要想实现还是调用派生类的还是就要使用虚函数概念 }有关虚函数可以看这篇文章#include <iostream>using namespace std; class Parent{public:Parent(int ii=0):i(ii){cout<<"Parent()\n";}Parent(const Parent& b):i(b.i){cout<<"Copy Parent()\n";}friend ostream& operator<<(ostream &os,const Parent&p){//除了赋值运算符,所有的重载运算符都能继承到派生类中return os<<"Parent::operator<<"<<p.i<<" ";}private:int i;};class Member{public:Member(int ii=0):i(ii){cout<<"Member()\n";}Member(const Member& m):i(m.i){cout<<"Copy Member()\n";}friend ostream& operator<<(ostream &os,const Member& m){return os<<"Member:: Operator<<"<<m.i<<" ";}private:int i;};class child:public Parent{public:child(int ii=0):Parent(ii),i(ii),m(ii){cout<<"Child()\n";}child(const child&c):Parent(c),i(c.i),m(c.m){//这里将child的对象赋给了parent的引用进行了向上的类型转换cout<<"Copy Child()\n";}friend ostream& operator<<(ostream& os,const child& c){return os<<(Parent&)c<<c.m<<" child::operator<<"<<c.i;}private:int i;Member m;};void main(){child c(2);child c1 =c;//调用基类parent的拷贝构造函数和member的拷贝构造函数构造自己cout<<c1<<endl;}#include <iostream>#include <string>using namespace std;class Instrument{public: virtual void play( ){cout<<"Instrument Play\n";}};class Wind:public Instrument{public:void play( ){cout<<"Wind Play\n";}};void main(){ Wind w; Instrument *p= &w; p->play();//基类指针调用派生类函数实现多态 Instrument&r=w; r.play();//基类引用调用派生类函数实现多态 ((Wind*)p)->play();//这是强制向下兼容,不安全}

对于向上兼容来说就是在传递地址,无论指针还是引用都是在传递地址,但是有没有想过如果传进去值会怎么样?????看一下程序

#include <iostream>#include <string>using namespace std;class Instrument{public: virtual void play( ){cout<<"Instrument Play\n";}};class Wind:public Instrument{public:void play( ){cout<<"Wind Play\n";}};void Transla(Instrument t){t.play();}void main(){ Wind w; Transla(w);}此时只会调用基类的play()函数,因为发生了对象切片,当把派生类的对象按值传给基类对象,此时直接就是把派生类对象压入栈中,但是此时会只拷贝属于基类的一部分,所以只能识别到基类的函数,这就相当于在派生类中将基类所需的部分切下来了 所谓对象切片就是建立对象的时候去掉不属于自己的部分然后拷贝过来,不像指针或者引用只是进行地址的传递,但是使用抽象类的纯虚函数就可以避免这种情况,比如上边的代码可以时基类是抽象类,抽象类编译器不允许建立对象,所以就会提示这种传值错误,抽象类与纯虚函数看这个文章

版权声明:本文为博主原创文章,未经博主允许不得转载。

上一篇对 malloc free ,new,delete 的思考与探索——2下一篇抽象类中定义纯虚函数

顶0踩0

,接受失败等于回归真实的自我,

C++的继承关于向上类型转换

相关文章:

你感兴趣的文章:

标签云: