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指針指着同一個地址時,就不重復構造。 其他的,構造函數和析構函數,基於第一個代碼列子。  根據自己對源碼的理解和測試的總結,如有錯誤,還請多多指正。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM