最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C++中的基類和派生類構(gòu)造函數(shù)示例詳解

 更新時間:2023年09月02日 09:53:04   作者:向陽逐夢  
這篇文章主要介紹了C++的基類和派生類構(gòu)造函數(shù),本文通過實例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下

基類的成員函數(shù)可以被繼承,可以通過派生類的對象訪問,但這僅僅指的是普通的成員函數(shù),類的構(gòu)造函數(shù)不能被繼承。構(gòu)造函數(shù)不能被繼承是有道理的,因為即使繼承了,它的名字和派生類的名字也不一樣,不能成為派生類的構(gòu)造函數(shù),當(dāng)然更不能成為普通的成員函數(shù)。

在設(shè)計派生類時,對繼承過來的成員變量的初始化工作也要由派生類的構(gòu)造函數(shù)完成,但是大部分基類都有 private 屬性的成員變量,它們在派生類中無法訪問,更不能使用派生類的構(gòu)造函數(shù)來初始化。

這種矛盾在C++繼承中是普遍存在的,解決這個問題的思路是:在派生類的構(gòu)造函數(shù)中調(diào)用基類的構(gòu)造函數(shù)。

下面的例子展示了如何在派生類的構(gòu)造函數(shù)中調(diào)用基類的構(gòu)造函數(shù):

    #include<iostream>
    using namespace std;
    //基類People
    class People{
    protected:
        char *m_name;
        int m_age;
    public:
        People(char*, int);
    };
    People::People(char *name, int age): m_name(name), m_age(age){}
    //派生類Student
    class Student: public People{
    private:
        float m_score;
    public:
        Student(char *name, int age, float score);
        void display();
    };
    //People(name, age)就是調(diào)用基類的構(gòu)造函數(shù)
    Student::Student(char *name, int age, float score): People(name, age), m_score(score){ }
    void Student::display(){
        cout<<m_name<<"的年齡是"<<m_age<<",成績是"<<m_score<<"。"<<endl;
    }
    int main(){
        Student stu("小明", 16, 90.5);
        stu.display();
        return 0;
    }

運行結(jié)果為:小明的年齡是16,成績是90.5。

請注意第 23 行代碼:

Student::Student(char *name, int age, float score): People(name, age), m_score(score){ }

People(name, age) 就是調(diào)用基類的構(gòu)造函數(shù),并將 name 和 age 作為實參傳遞給它, m_score(score) 是派生類的參數(shù)初始化表,它們之間以逗號 , 隔開。也可以將基類構(gòu)造函數(shù)的調(diào)用放在參數(shù)初始化表后面:

Student::Student(char *name, int age, float score): m_score(score), People(name, age){ }

但是不管它們的順序如何,派生類構(gòu)造函數(shù)總是先調(diào)用基類構(gòu)造函數(shù)再執(zhí)行其他代碼(包括參數(shù)初始化表以及函數(shù)體中的代碼),總體上看和下面的形式類似:

    Student::Student(char *name, int age, float score){
        People(name, age);
        m_score = score;
    }

當(dāng)然這段代碼只是為了方便大家理解,實際上這樣寫是錯誤的,因為基類構(gòu)造函數(shù)不會被繼承,不能當(dāng)做普通的成員函數(shù)來調(diào)用。換句話說,只能將基類構(gòu)造函數(shù)的調(diào)用放在函數(shù)頭部,不能放在函數(shù)體中。另外,函數(shù)頭部是對基類構(gòu)造函數(shù)的調(diào)用,而不是聲明,所以括號里的參數(shù)是實參,它們不但可以是派生類構(gòu)造函數(shù)參數(shù)列表中的參數(shù),還可以是局部變量、常量等,例如

Student::Student(char *name, int age, float score): People("小明", 16), m_score(score){ }

構(gòu)造函數(shù)的調(diào)用順序

從上面的分析中可以看出,基類構(gòu)造函數(shù)總是被優(yōu)先調(diào)用,這說明創(chuàng)建派生類對象時,會先調(diào)用基類構(gòu)造函數(shù),再調(diào)用派生類構(gòu)造函數(shù),如果繼承關(guān)系有好幾層的話,例如:

A --> B --> C

那么創(chuàng)建 C 類對象時構(gòu)造函數(shù)的執(zhí)行順序為:

A類構(gòu)造函數(shù) --> B類構(gòu)造函數(shù) --> C類構(gòu)造函數(shù)

構(gòu)造函數(shù)的調(diào)用順序是按照繼承的層次自頂向下、從基類再到派生類的。還有一點要注意,派生類構(gòu)造函數(shù)中只能調(diào)用直接基類的構(gòu)造函數(shù),不能調(diào)用間接基類的。

以上面的 A、B、C 類為例,C 是最終的派生類,B 就是 C 的直接基類,A 就是 C 的間接基類。

C++ 這樣規(guī)定是有道理的,因為我們在 C 中調(diào)用了 B 的構(gòu)造函數(shù),B 又調(diào)用了 A 的構(gòu)造函數(shù),相當(dāng)于 C 間接地(或者說隱式地)調(diào)用了 A 的構(gòu)造函數(shù),如果再在 C 中顯式地調(diào)用 A 的構(gòu)造函數(shù),那么 A 的構(gòu)造函數(shù)就被調(diào)用了兩次,相應(yīng)地,初始化工作也做了兩次,這不僅是多余的,還會浪費CPU時間以及內(nèi)存,毫無益處,所以 C++ 禁止在 C 中顯式地調(diào)用 A 的構(gòu)造函數(shù)。 

基類構(gòu)造函數(shù)調(diào)用規(guī)則

事實上,通過派生類創(chuàng)建對象時必須要調(diào)用基類的構(gòu)造函數(shù),這是語法規(guī)定。換句話說,定義派生類構(gòu)造函數(shù)時最好指明基類構(gòu)造函數(shù);如果不指明,就調(diào)用基類的默認(rèn)構(gòu)造函數(shù)(不帶參數(shù)的構(gòu)造函數(shù));如果沒有默認(rèn)構(gòu)造函數(shù),那么編譯失敗。請看下面的例子:

    #include <iostream>
    using namespace std;
    //基類People
    class People{
    public:
        People();  //基類默認(rèn)構(gòu)造函數(shù)
        People(char *name, int age);
    protected:
        char *m_name;
        int m_age;
    };
    People::People(): m_name("xxx"), m_age(0){ }
    People::People(char *name, int age): m_name(name), m_age(age){}
    //派生類Student
    class Student: public People{
    public:
        Student();
        Student(char*, int, float);
    public:
        void display();
    private:
        float m_score;
    };
    Student::Student(): m_score(0.0){ }  //派生類默認(rèn)構(gòu)造函數(shù)
    Student::Student(char *name, int age, float score): People(name, age), m_score(score){ }
    void Student::display(){
        cout<<m_name<<"的年齡是"<<m_age<<",成績是"<<m_score<<"。"<<endl;
    }
    int main(){
        Student stu1;
        stu1.display();
        Student stu2("小明", 16, 90.5);
        stu2.display();
        return 0;
    }

運行結(jié)果:xxx的年齡是0,成績是0。

小明的年齡是16,成績是90.5。

創(chuàng)建對象 stu1 時,執(zhí)行派生類的構(gòu)造函數(shù) Student::Student() ,它并沒有指明要調(diào)用基類的哪一個構(gòu)造函數(shù),從運行結(jié)果可以很明顯地看出來,系統(tǒng)默認(rèn)調(diào)用了不帶參數(shù)的構(gòu)造函數(shù),也就是 People::People()

創(chuàng)建對象 stu2 時,執(zhí)行派生類的構(gòu)造函數(shù) Student::Student(char *name, int age, float score) ,它指明了基類的構(gòu)造函數(shù)。

在第 27 行代碼中,如果將 People(name, age) 去掉,也會調(diào)用默認(rèn)構(gòu)造函數(shù),第 37 行的輸出結(jié)果將變?yōu)椋簒xx的年齡是0,成績是90.5。

如果將基類 People 中不帶參數(shù)的構(gòu)造函數(shù)刪除,那么會發(fā)生編譯錯誤,因為創(chuàng)建對象 stu1 時需要調(diào)用 People 類的默認(rèn)構(gòu)造函數(shù), 而 People 類中已經(jīng)顯式定義了構(gòu)造函數(shù),編譯器不會再生成默認(rèn)的構(gòu)造函數(shù)。

到此這篇關(guān)于C++的基類和派生類構(gòu)造函數(shù)的文章就介紹到這了,更多相關(guān)C++基類構(gòu)造函數(shù)內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • C實現(xiàn)的非阻塞方式命令行端口掃描器源碼

    C實現(xiàn)的非阻塞方式命令行端口掃描器源碼

    這篇文章主要介紹了C實現(xiàn)的非阻塞方式命令行端口掃描器源碼,對于大家理解C端口掃描器有很大幫主,需要的朋友可以參考下
    2014-07-07
  • QT編寫地圖實現(xiàn)設(shè)備點位的示例代碼

    QT編寫地圖實現(xiàn)設(shè)備點位的示例代碼

    在地圖應(yīng)用的相關(guān)項目中,在地圖上標(biāo)識一些設(shè)備點,并對點進行交互這個功能用的最多的,于是需要一套機制可以動態(tài)的添加、刪除、清空、重置。本文將詳細(xì)介紹這些功能如何實現(xiàn),需要的可以參考一下
    2022-01-01
  • c++的virtual和override作用及說明

    c++的virtual和override作用及說明

    這篇文章主要介紹了c++的virtual和override作用及說明,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-11-11
  • C++虛繼承的實現(xiàn)原理由內(nèi)存布局開始講起

    C++虛繼承的實現(xiàn)原理由內(nèi)存布局開始講起

    為了解決多繼承時的命名沖突和冗余數(shù)據(jù)問題,C++提出了虛繼承,使得在派生類中只保留一份間接基類的成員,下面我們從內(nèi)存布局看看虛繼承的實現(xiàn)原理
    2022-06-06
  • 深入C++可見性與生命期的區(qū)別詳解

    深入C++可見性與生命期的區(qū)別詳解

    本篇文章對C++中可見性與生命期的區(qū)別進行了詳細(xì)的分析介紹,需要的朋友參考下
    2013-05-05
  • C/C++編程語言中的指針(pointer)你了解嗎

    C/C++編程語言中的指針(pointer)你了解嗎

    這篇文章主要為大家詳細(xì)介紹了C/C++編程語言中的指針,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2022-02-02
  • Qt 中開啟線程的多種方式小結(jié)

    Qt 中開啟線程的多種方式小結(jié)

    本篇文章就來整理一下 Qt 中使用線程的五種方式,方便后期回顧。前面兩種比較簡單,一筆帶過了,主要介紹后面三種,感興趣的朋友跟隨小編一起看看吧
    2021-09-09
  • C語言數(shù)據(jù)結(jié)構(gòu)之二叉樹的非遞歸后序遍歷算法

    C語言數(shù)據(jù)結(jié)構(gòu)之二叉樹的非遞歸后序遍歷算法

    這篇文章主要介紹了C語言數(shù)據(jù)結(jié)構(gòu)之二叉樹的非遞歸后序遍歷算法的相關(guān)資料,希望通過本文能幫助到大家,讓大家實現(xiàn)這樣的功能,需要的朋友可以參考下
    2017-10-10
  • QT基于TCP網(wǎng)絡(luò)聊天室

    QT基于TCP網(wǎng)絡(luò)聊天室

    這篇文章主要為大家詳細(xì)介紹了QT基于TCP網(wǎng)絡(luò)聊天室,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-08-08
  • C語言數(shù)據(jù)結(jié)構(gòu)堆的基本操作實現(xiàn)

    C語言數(shù)據(jù)結(jié)構(gòu)堆的基本操作實現(xiàn)

    這篇文章主要為大家介紹了C語言數(shù)據(jù)結(jié)構(gòu)堆的基本操作實現(xiàn)示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2021-11-11

最新評論

建阳市| 高安市| 神池县| 小金县| 中方县| 武陟县| 宜春市| 石阡县| 榆林市| 宁都县| 婺源县| 会理县| 牟定县| 光泽县| 永定县| 富锦市| 方山县| 霍林郭勒市| 汨罗市| 富源县| 会同县| 罗甸县| 永城市| 商城县| 开原市| 吴旗县| 通州区| 循化| 天水市| 克什克腾旗| 海盐县| 罗田县| 资中县| 天祝| 巧家县| 霍林郭勒市| 图木舒克市| 化隆| 阜城县| 皋兰县| 荃湾区|