继承关系总结


一、父类与子类

1.父类与子类的相互转换

派生类的对象可以赋给基类,反之不行

基类的指针可以指向派生类,反之不行
基类的引用可以初始化为派生类的对象,反之不行

派生类指针必须强制转换为基类指针后才可以指向基类

基类指针转换为派生类指针容易导致崩溃性错误

虚基类的引用或派生不能转换为派生类
[cpp]  view plain  copy
  1. class father{};  
  2. class son:public father{};  
  3. int main()  
  4. {  
  5.     father f;  
  6.     son s;  
  7.     f = s;//正确  
  8.     s = f;//错误  
  9.   
  10.     father *pf = new son;//正确  
  11.     son *ps = new father;//错误  
  12.   
  13.     father &rf = s;//正确  
  14.     father &rs = f;//错误  
  15.     return 0;  
  16. }  

2.继承关系对基类成员的影响

 公有成员保护成员私有成员
公有继承公有保护不可访问
保护继承保护保护不可访问
私有继承私有私有不可访问
成员函数111
对象100
子类110
1:可以访问 0:不可访问
当所有成员都变成不可访问时,再往下派生就没有意义了

二、子类的构造与析构

1.构造派生类对象时,先执行基类的构造函数,再执行子类的构造函数,析构反之
[cpp]  view plain  copy
  1. class father  
  2. {  
  3. public:  
  4.     father(){cout<<"father construct"<<endl;}  
  5.     ~father(){cout<<"father delete"<<endl;}  
  6. };  
  7. class son : public father  
  8. {  
  9. public:  
  10.     son(){cout<<"son construct"<<endl;}  
  11.     ~son(){cout<<"son delete"<<endl;}  
  12. };  
  13. int main()  
  14. {  
  15.     son s;  
  16.     return 0;  
  17. }  

输出:

father construct
son construct
son delete
father delete

2.如果是多重继承,基类的构造顺序按给定的顺序,析构反之
[cpp]  view plain  copy
  1. class father  
  2. {  
  3. public:  
  4.     father(){cout<<"father construct"<<endl;}  
  5.     ~father(){cout<<"father delete"<<endl;}  
  6. };  
  7. class mother  
  8. {  
  9. public:  
  10.     mother(){cout<<"mother construct"<<endl;}  
  11.     ~mother(){cout<<"mother delete"<<endl;}  
  12. };  
  13. class son : public father, public mother  
  14. {  
  15. public:  
  16.     son(){cout<<"son construct"<<endl;}  
  17.     ~son(){cout<<"son delete"<<endl;}  
  18. };  
  19. int main()  
  20. {  
  21.     son s;  
  22.     return 0;  
  23. }  

输出:

father construct
mother construct
son construct
son delete
mother delete
father delete

3.利用基类的构造函数构造子类,效率更高
[cpp]  view plain  copy
  1. class father  
  2. {  
  3.     int x;  
  4. public:  
  5.     father(int a):x(a){cout<<"father construct:"<<x<<endl;}  
  6. };  
  7. class son : public father  
  8. {  
  9.     int y;  
  10. public:  
  11.     son(int a, int b):father(a), y(b){cout<<"son construct:"<<y<<endl;}  
  12. };  
  13. int main()  
  14. {  
  15.     son s(1, 2);  
  16.     return 0;  
  17. }  

输出:

father construct:1
son construct:2


三、多重继承

1.多重继续的二义性,根本原因是

假如A有Test(),则B和C都有Test(),于是D产生了二义性

[cpp]  view plain  copy
  1. class A  
  2. {  
  3. public:  
  4.     void Test(){cout<<"A"<<endl;}  
  5. };  
  6. class B  
  7. {  
  8. public:  
  9.     void Test(){cout<<"B"<<endl;}  
  10. };  
  11. class C : public A, public B  
  12. {  
  13. };  
  14. int main()  
  15. {  
  16.     C c;             
  17.     c.Test();      //错误  
  18.     c.A::Test();   //正确,输出:A  
  19.     c.B::Test();   //正确,输出:B  
  20.     return 0;  
  21. }  

2.编译器通常都是从离自己最近的目录树向上搜索的

子类的Test()覆盖了基类的Test(),并不代表基类的Test()消失,只是不能直接访问

[cpp]  view plain  copy
  1. class A  
  2. {  
  3. public:  
  4.     void Test(){cout<<"A"<<endl;}  
  5. };  
  6. class B  
  7. {  
  8. public:  
  9.     void Test(){cout<<"B"<<endl;}  
  10. };  
  11. class C : public A, public B  
  12. {  
  13.     void Test(){cout<<"C"<<endl;}  
  14. };  
  15. int main()  
  16. {  
  17.     C c;             
  18.     c.Test();      //正确,输出:C  
  19.     c.A::Test();   //正确,输出:A  
  20.     c.B::Test();   //正确,输出:B  
  21.     return 0;  
  22. }  


 

3.对于单一继承,子类能否访问父类的父类,只与继承的方式有关

对于多重继承,子类不能直接访问父类的父类。
 

4.用virtual来避免二义性。

class B : virtual public A.


四、继承与包含

1.一个类的成员变量列表中包含另一个类的对象,叫做包含(包容)。

2.包含与私有继承的区别:

包含:

1)使程序看上去更清晰易懂

2)不存在继承带来的问题

3)可以包括另一个类的多个对象

私有继承:

1)可以访问基类的保护成员

2)可以重定义虚函数,实现多态


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值