亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

C++中的基類和派生類構造函數示例詳解

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

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

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

這種矛盾在C++繼承中是普遍存在的,解決這個問題的思路是:在派生類的構造函數中調用基類的構造函數。

下面的例子展示了如何在派生類的構造函數中調用基類的構造函數:

    #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)就是調用基類的構造函數
    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;
    }

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

請注意第 23 行代碼:

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

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

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

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

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

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

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

構造函數的調用順序

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

A --> B --> C

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

A類構造函數 --> B類構造函數 --> C類構造函數

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

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

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

基類構造函數調用規(guī)則

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

    #include <iostream>
    using namespace std;
    //基類People
    class People{
    public:
        People();  //基類默認構造函數
        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){ }  //派生類默認構造函數
    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;
    }

運行結果:xxx的年齡是0,成績是0。

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

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

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

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

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

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

相關文章

  • 詳解C++11中的線程庫

    詳解C++11中的線程庫

    線程是操作系統(tǒng)中的一個概念,線程對象可以關聯一個線程,用來控制線程以及獲取線程的狀態(tài),這篇文章主要介紹了C++11中的線程庫的相關知識,需要的朋友可以參考下
    2022-01-01
  • C語言鍵盤控制走迷宮小游戲

    C語言鍵盤控制走迷宮小游戲

    這篇文章主要為大家詳細介紹了C語言鍵盤控制走迷宮小游戲,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-06-06
  • C++教程之array數組使用示例詳解

    C++教程之array數組使用示例詳解

    這篇文章主要為大家介紹了C++教程之array數組使用示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-03-03
  • Visual Studio2022+QT6創(chuàng)建桌面應用實現

    Visual Studio2022+QT6創(chuàng)建桌面應用實現

    本文主要介紹了Visual Studio2022+QT6創(chuàng)建桌面應用實現,文中通過圖文介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2024-02-02
  • C++中的數組你真的理解了嗎

    C++中的數組你真的理解了嗎

    這篇文章主要為大家詳細介紹了C++的數組,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2022-02-02
  • 帶你了解C++的動態(tài)內存分配

    帶你了解C++的動態(tài)內存分配

    今天小編就為大家分享一篇關于關于C++動態(tài)分配內存的介紹,小編覺得內容挺不錯的,現在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧
    2021-08-08
  • C語言/C++中如何產生隨機數

    C語言/C++中如何產生隨機數

    這里要用到的是rand()函數, srand()函數,和time()函數。需要說明的是,iostream頭文件中就有srand函數的定義,不需要再額外引入stdlib.h;而使用time()函數需要引入ctime頭文件
    2013-10-10
  • 高效實現整型數字轉字符串int2str的方法

    高效實現整型數字轉字符串int2str的方法

    下面小編就為大家?guī)硪黄咝崿F整型數字轉字符串int2str的方法。小編覺得挺不錯的,現在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-03-03
  • 10行C++代碼實現高性能HTTP服務

    10行C++代碼實現高性能HTTP服務

    這篇文章主要介紹了10行C++代碼如何實現高性能HTTP服務,幫助大家更好的理解和學習使用c++,感興趣的朋友可以了解下
    2021-04-04
  • C++中的友元函數與友元類詳情

    C++中的友元函數與友元類詳情

    這篇文章主要介紹了C++中的友元函數與友元類詳情,對類的封裝是C++三大特性中的一個重要特性,封裝好的數據在類的外部是訪問不到的但是一旦出了問題,想要操作被封裝的數據怎么辦呢?由此友元函數友元類誕生了,下文我們來詳細來接一下具體的有緣類吧
    2022-02-02

最新評論