c++那些事兒3.0 繼承

    一般形式   
     class class_name:繼承方式 基類名{ code   }
         繼承方式有三種: public ,protected,private.   //java好像都是public繼承。
     單繼承
     多繼承,多繼承會(huì)很復(fù)雜,所以java,c sharp都采用interface。
  類函數(shù):
     構(gòu)造函數(shù)
           先執(zhí)行父類的構(gòu)造函數(shù),在執(zhí)行子類的構(gòu)造函數(shù)。
           一般形式  派生類的構(gòu)造函數(shù)(參數(shù)列表):基類構(gòu)造函數(shù)名(參數(shù)列表}{ code}
     析構(gòu)函數(shù)
           先構(gòu)造的后析構(gòu),后構(gòu)造的先析構(gòu)。
     虛函數(shù)。
     避免二義性。但是最后的派生類不僅負(fù)責(zé)對(duì)直接基類初始化,還要對(duì)虛基類初始化。



看code是最有用的,細(xì)節(jié)情況已經(jīng)注釋說(shuō)明。

#include<iostream>
#include<string>
using namespace std;
     // 類A
class A {
  protected:
    string name;
    int id;
    double da;
private:
    double pa; //這個(gè)數(shù)據(jù)繼承后不能被訪問(wèn)
 public:
     A(string name, int id) {
         cout << "A的構(gòu)造函數(shù)執(zhí)行"<<endl;
         this->name = name;   //this指針
         this->id = id;
         this->da = da;
     }

     void setDa(double d) {
         da = d;
     }

     ~A() {
         cout << "A的析構(gòu)函數(shù)"<<endl;
     }

    void setId(int id) {
//id是私有數(shù)據(jù)成員,不能被繼承,類外不能訪問(wèn),通過(guò)函數(shù)才能
        this->id = id;
     }

     void print() {
         cout << "string=" << name << "  " << "id=" << id<< endl;
     }

};
// 注意 C++中類的結(jié)尾是有;的,和java不同,我vs,ide編輯沒(méi)有在意。

//如果不寫關(guān)鍵字,默認(rèn)為private。
class B :virtual public A {
    //B類public繼承A類,但是私有數(shù)據(jù)成員不能訪問(wèn)。
  protected:
    int id;  //A類的id成員被覆蓋了。

  public:
  /*
  父類構(gòu)造函數(shù)的初始化通過(guò)子類構(gòu)造函數(shù)初始化列表實(shí)現(xiàn),
  */
    
      B(string na,int ida,int idb):A(na,ida){
          cout << "B的構(gòu)造函數(shù)執(zhí)行"<<endl;
          this->id = idb;
      }
      ~B() {
          cout << "B的析構(gòu)函數(shù)"<<endl;
      }

      void  print() {
          /*
          基類同名的數(shù)據(jù)成員在派生類被覆蓋,成為不可見。
          */
          cout << "A類被繼承的ID:" << A::id << endl;
          cout <<"name:B"<< name<<" "<<"id:"<<id<<endl; //name是繼承A的。
      }

};

class C:virtual public A{

    //B類public繼承A類,但是私有數(shù)據(jù)成員不能訪問(wèn)。
protected:
    int id; 

public:
    /*
    父類構(gòu)造函數(shù)的初始化通過(guò)子類構(gòu)造函數(shù)初始化列表實(shí)現(xiàn),
    */
    C(string na,int ida,int idc) :A(na,ida) {
        cout << "C的構(gòu)造函數(shù)執(zhí)行" << endl;
        this->id = idc;
    }
    ~C() {
        cout << "C的析構(gòu)函數(shù)" << endl;
    }

    void  print() {
        cout << "name:C" << name << " " << "id:" << id << endl;; //name是繼承A的。
        
    }
};

//D類繼承B,C, 因?yàn)锽,C都繼承A,所以D類有2份A,這樣就會(huì)出現(xiàn)二義性問(wèn)題。
class D :public B,public C {
 public:
     void showId() {
        /* cout << "id::" << id << endl;
           如果這樣,就會(huì)產(chǎn)生二義性,D公有繼承了B,C protedted的id,
           這里不知道訪問(wèn)哪一個(gè)。 但是可以通過(guò)域運(yùn)算符指定A,B,C繼承來(lái)的id。
        */
         cout << "id::A" <<A::id << endl;
                  //通過(guò)域運(yùn)算符指定id。
     }

     /*
      D繼承了,B,C。B,C繼承了A,即繼承了double da;
      怎么訪問(wèn)它了。
          cout<<da;
          cout<<A::da; 都不行,無(wú)法指出是繼承B的,還是C的。
           所以就要虛基類了。
     */
     void showDa() {

         cout << "B::da" << B::da << endl;
     }
     /*
     在以前派生類只對(duì)其直接基類初始化,在由其直接子類對(duì)間接子類初始化
     現(xiàn)在由于虛基類在派生類只有一份拷貝,所以這份數(shù)據(jù)必須由派生類給出。
     因?yàn)轭怋,類C可能給出不同的構(gòu)造函數(shù),這樣對(duì)虛基類初始化會(huì)產(chǎn)生矛盾。
     */

     D(string na, int ida, int idc) :C(na, ida, idc),
         B(na, ida, idc), A(na, ida)
     {
         cout << "D的構(gòu)造函數(shù)執(zhí)行" << endl;
     }
     ~D() {
         cout << "D的析構(gòu)函數(shù)" << endl;
     }

 
};

int main() {


    A a("name_A", 111);
    a.print();
    cout << "-----------------------------" << endl;
    //先執(zhí)行父類的構(gòu)造函數(shù),在執(zhí)行基類的構(gòu)造函數(shù)
    B b("name_B",111, 222);
    //這里是B的id,因?yàn)閜rivate屬性在子類不能訪問(wèn)。
    b.print();
    cout << "-----------------------------" << endl;
    C c("name_C", 111, 333);
    //這里是B的id,因?yàn)閜rivate屬性在子類不能訪問(wèn)。
    c.print();
    cout << "-----------------------------" << endl;


    D d("name_D", 111, 444);

    // id的二義性 可以通過(guò) ::域運(yùn)算符指定,解決。
       d.showId();

     // 準(zhǔn)備驗(yàn)證double da; 產(chǎn)生二義性的情況,這個(gè)就只能通過(guò)虛基類確定。
      //   setDa() 是會(huì)產(chǎn)生二義性的函數(shù),但是A是虛基類。
       d.setDa(3.1415926);
       d.showDa();
       cout << "-----------------------------" << endl;

    
     system("pause");  //vs要看析構(gòu)函數(shù)要去掉這一句。
    return 0;
}


結(jié)果如下,可以對(duì)照代碼分析

結(jié)果圖.PNG

這里main函數(shù)的代碼如下:

int main() {
       D d("name_D", 111, 444);
    // id的二義性 可以通過(guò) ::域運(yùn)算符指定,解決。
       d.showId();

     // 準(zhǔn)備驗(yàn)證double da; 產(chǎn)生二義性的情況,這個(gè)就只能通過(guò)虛基類確定。
      //   setDa() 是會(huì)產(chǎn)生二義性的函數(shù),但是A是虛基類。
       d.setDa(3.1415926);
       d.showDa();
       cout << "-----------------------------" << endl;

                                     /*  vs選擇開始執(zhí)行但不調(diào)試 */
    // system("pause");  //vs要看析構(gòu)函數(shù)要去掉這一句。
    return 0;
}


構(gòu)造函數(shù)和析構(gòu)函數(shù)執(zhí)行順序驗(yàn)證

只保留了D類.PNG



東西好多啊,c++ 講個(gè)語(yǔ)法就不少東西了

 虛函數(shù),多態(tài)性,這個(gè)代碼挖了坑,后面在講,好累啊。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 1.面向?qū)ο蟮某绦蛟O(shè)計(jì)思想是什么? 答:把數(shù)據(jù)結(jié)構(gòu)和對(duì)數(shù)據(jù)結(jié)構(gòu)進(jìn)行操作的方法封裝形成一個(gè)個(gè)的對(duì)象。 2.什么是類?...
    少帥yangjie閱讀 5,124評(píng)論 0 14
  • 一、 C/C++程序基礎(chǔ) 面試?yán)}1——分析代碼寫輸出(一般賦值語(yǔ)句的概念和方法)。 面試?yán)}2—...
    LuckTime閱讀 2,112評(píng)論 2 42
  • 姓名:程英鑫 學(xué)號(hào):16020140082 學(xué)院:電子工程學(xué)院 轉(zhuǎn)載自:頭條號(hào) 有刪減 【嵌牛導(dǎo)讀】:每當(dāng)瀏...
    落意秋濃閱讀 421評(píng)論 0 0
  • 不減肥的結(jié)果,老板,來(lái)兩碗,管飽就行。。。吃貨在下那么大的雷陣雨,依然執(zhí)著前往可以一家,比較溫馨的米線館,小城在午...
    楊二燦閱讀 245評(píng)論 0 0
  • 2017 11 15 晴 星期三 兒子晚上回來(lái),自己進(jìn)房間寫作業(yè),我抱著二寶,時(shí)不時(shí)的偷偷的瞄一眼,看看是不...
    99d29bce557c閱讀 161評(píng)論 0 0

友情鏈接更多精彩內(nèi)容