程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> C++繼承與派生(原理歸納)

C++繼承與派生(原理歸納)

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

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved