前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >C++继承与派生(原理归纳)

C++继承与派生(原理归纳)

作者头像
Gxjun
发布2018-03-26 16:08:40
1.1K0
发布2018-03-26 16:08:40
举报
文章被收录于专栏:mlml

   1.   C++继承与java不同,java遵循单继承,但java的接口为其不足做了很好的弥补了。 C++则是灵活的多,为多继承。即一个C++类可以同时继承N个类的属性。

2. 对于继承方式 :

    有三种:  public ,private,protect,对于public继承的类,其公有成员依然是公有成员,私有成员依旧是私有成员。  

    对于protect,private 则有限制 ,就好比一个水管,公有水管是最大号的,对于水的流量没有限制。保护水管,是中等的号的,对于大号水管的流量使其变成中等流量,对于中等以下的不限制。私有水管,则是最小号的,对于大于私有水管限制的统统的改为私有水管的标准。 其中私有继承,其实就是一种绝育的措施。就是以后的继承就没有太大意义。

3.对于继承关于构造和析构顺序原里的归纳:

看代码:

代码语言:javascript
复制
 1 #include<iostream>
 2 using namespace std ;
 3 
 4 class Base1 {
 5 
 6 public :
 7     Base1() {
 8         cout << "Default Base1"  << endl;
 9     }
10     Base1(int i) {
11         cout << "Base1"<<i<< endl;
12     }
13     ~Base1() {
14         cout << "Base1 析构" << endl;
15     }
16 };
17 
18 class Base2 {
19 
20 public :
21     Base2() {
22         cout << "Default Base2"  << endl;
23     }
24     ~Base2() {
25         cout << "Base2 析构" << endl;
26     }
27     Base2(int i) {
28         cout << "Base2" << i << endl;
29     }
30 };
31 class Base3 {
32 
33 public :
34     Base3() {
35         cout << "Default Base3" << endl;
36     }
37     ~Base3() {
38         cout << "Base3 析构" << endl;
39     }
40     Base3(int i) {
41         cout << "Base3" << i << endl;
42     }
43 
44 };
45 
46 
47 class Derived : public Base1, public Base2, public Base3  //(1)先 在这儿开始构造从左到右
48      //析构则是从右到左
49 {
50 
51 public :
52     Derived() {
53         cout << "Default Derived" << endl;
54     }
55     ~Derived() {
56         cout << "Derived 析构" << endl;
57     }
58     Derived( int a , int  b , int c , int d )  
59         :men2(b),Base1(a),Base3(c), Base2(d),men1(b) {   
60         cout << "Derived" << endl;
61     };
62 
63 private :
64     //构造从左到右
65     Base3 men3;
66     Base2 men2;
67     Base1 men1;
68 
69     //析构则是从底部开始往上析构,先 Base 1,2,3
70 };
71 
72 int main(void ) {
73 
74     Derived obj(1,2,3,4);
75     return 0;
76     
77 }

4. 以上是对于单继承的描述,如果是多继承,那么常规的话,我们很容易清楚器执行顺序,但是如果是虚继承,其执行顺序又会如何 ?

    1. 现在我们来看这样一个图:它的运行结果又是如何.......

代码语言:javascript
复制
  1 #include<iostream>
  2 using namespace std;
  3 
  4 class Boss {
  5 
  6 public :
  7     Boss() {
  8         cout << "this is Boss's constructor !" << endl;
  9     };
 10     Boss(int i) {
 11         cout << "this is Boss's constructor !" \
 12             << " moneny=" << i << endl;
 13     }
 14 
 15     void show() {
 16       cout<<"宝剑磨砺,斩魂妖,时光磨砂,魔刃出"<<endl;
 17     }
 18     virtual ~ Boss() {
 19         cout << "this is Boss's xigou function !" << endl;
 20     };    //虚析构函数
 21 };
 22 
 23 //店小二
 24 class xiao_er :virtual public Boss
 25 {
 26  public:
 27      xiao_er() {
 28          cout << "this is xiao_er's constructor !"<<endl;
 29      }
 30      xiao_er(int i) : Boss(i){
 31          cout << "this is xiao_er's constructor !" \
 32              << " moneny=" << i << endl;
 33      }
 34      virtual ~xiao_er() {
 35          cout << "this is xiao_er's xigou function !" << endl;
 36      }
 37      void show() {
 38          cout << "我是店小二,客官 !" << endl;
 39      }
 40 };
 41 
 42 //王二小
 43 class er_xiao : virtual public Boss \
 44      , virtual public  xiao_er /*其实这里这个可以省去,但是这儿是为了写代码而写代码*/
 45 {
 46  public :
 47      er_xiao() {
 48          cout << "this is er_xiao's constructor !" << endl;
 49      }
 50      er_xiao(int i) : \
 51      Boss(i) , xiao_er(i+1)
 52      {
 53          cout << "this is er_xiao's constructor !" \
 54              << " moneny=" << i << endl;
 55      }
 56     virtual ~ er_xiao() {
 57          cout << "this is er_xiao's xigou function !"<<endl;
 58      }
 59      void show() {
 60          cout << "我是王二小,为坏人带路的王二小 !" << endl;
 61      }
 62 };
 63 
 64 //天朝VIP员工
 65 class VIP_em : virtual public Boss
 66 {
 67 
 68 public:
 69     VIP_em(){
 70         cout << "this is VIP_em's constructor !" << endl;
 71     }
 72 
 73     VIP_em(int i) : \
 74      Boss(i)
 75     {
 76         cout << "this is VIP_em's constructor !" \
 77             << " moneny=" << i << endl;
 78     }
 79     virtual ~VIP_em() {
 80         cout << "this is VIP_em's xigou function !" << endl;
 81     }
 82     void show() {
 83         cout << "我是VIP , 我有特权! "<<endl;
 84     }
 85 };
 86 
 87 //熊孩子
 88 class stupid_kid : virtual public VIP_em \
 89     , virtual public xiao_er , \
 90     virtual public er_xiao
 91 {
 92  public:
 93      stupid_kid() {
 94          cout << "this is stupid_kid's constructor !" << endl;
 95      }
 96 
 97      stupid_kid(int i) : \
 98          VIP_em(i) , xiao_er(12) , er_xiao(13),xe(i)
 99      {
100          cout << "this is stupid_kid's constructor !" \
101             <<" moneny="<<i<<endl;
102      }
103      ~stupid_kid() {
104        cout << "this is stupid_kid's xigou function !"<<endl;
105      }
106 
107      void show() {
108          cout << "我是熊孩子,蜀黍,蜀黍,抱抱!" << endl;
109      }
110 private :
111     VIP_em vi;
112     xiao_er xe;
113     er_xiao ex;
114 };
115 
116 int main(){
117 
118     stupid_kid  st(100);
119     //父类的函数被覆盖了
120      st.show();
121     //如何调用父类,强制是一种。
122      ((Boss)st).show();
123     
124     //stupid_kid *pt = &st;
125     //stupid_kid  &sb = st;
126     // pt->show();
127     //((Boss)sb).show();
128     return 0;
129 }

结果为:

this is Boss's constructor ! this is VIP_em's constructor ! moneny=100 this is xiao_er's constructor ! moneny=12 this is er_xiao's constructor ! moneny=13

                                                      -------------这部分为熊孩子的继承部分构造函数

下面是私有变量的构造函数

this is Boss's constructor !  this is VIP_em's constructor !

                                  ------私有变量 Vip_em调用无参数的构造函数  this is Boss's constructor ! moneny=100  this is xiao_er's constructor ! moneny=100

                                 ------私有变量  xiao_er调用有参数的构造函数 

this is Boss's constructor ! this is xiao_er's constructor !

                                  ------私有变量 xiao_er调用无参数的构造函数  this is er_xiao's constructor !

this is stupid_kid's constructor ! moneny=100 我是熊孩子,蜀黍,蜀黍,抱抱! 宝剑磨砺,斩魂妖,时光磨砂,魔刃出 this is Boss's xigou function ! this is stupid_kid's xigou function ! this is er_xiao's xigou function ! this is xiao_er's xigou function ! this is Boss's xigou function ! this is xiao_er's xigou function ! this is Boss's xigou function ! this is VIP_em's xigou function ! this is Boss's xigou function ! this is er_xiao's xigou function ! this is xiao_er's xigou function ! this is VIP_em's xigou function ! this is Boss's xigou function ! 请按任意键继续. . .

6、 从上述代码可以不难看出,  虚内继承,避免了二义性,仅仅压缩了公有的你虚类继承类。

如果要弄清楚虚拟继承,就得先知道virtual table (vtbl) ----我们说的虚函数表

   在内存那块, 会留 下一块连续的内存块,用作vtble存储JMP地址,而vtble里头存的便是virtual function(虚函数)地址,

每次继承时,基类都会产生一个vptr指针,指向派生类的地质,当 vptr指针指着同一个地址时,就不重复构造。 其他的,构造函数和析构函数,基于第一个代码列子。  根据自己对源码的理解和测试的总结,如有错误,还请多多指正。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2015-03-22 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档