首页 > 代码库 > C++继承与派生(原理归纳)

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

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

    技术分享

2. 对于继承方式 :

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

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

 

技术分享

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

看代码:

  

 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 }

结果:

   

Base11
Base24
Base33
Default Base3
Base22
Base12
Derived
Derived 析构
Base1 析构
Base2 析构
Base3 析构
Base3 析构
Base2 析构
Base1 析构
请按任意键继续. . .

 

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

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

   技术分享

  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指针指着同一个地址时,就不重复构造。 其他的,构造函数和析构函数,基于第一个代码列子。  根据自己对源码的理解和测试的总结,如有错误,还请多多指正。

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