這篇文章主要講解了“c++繼承中的構造與析構方法是什么”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“c++繼承中的構造與析構方法是什么”吧!

我們思考下這個問題:如何初始化父類成員?父類構造函數和子類構造函數有何關系呢?在子類中可以定義構造函數,子類構造函數必須對繼承而來的成員進行初始化:a> 直接通過初始化列表或者賦值的方式進行初始化;b> 調用父類構造函數進行初始化。
下來我們來說說父類構造函數在子類中的調用方式,分為兩種:a> 默認調用:適用于無參構造函數和使用默認參數的構造函數;b> 顯示調用:通過初始化列表進行調用,適用于所有父類構造函數。那么隱式調用是在子類的構造函數中啥都不加,顯示調用時在子類構造函數后加上父類構造函數,如下所示

下來我們就對子類的構造函數一探究竟
#include <iostream>
#include <string>
using namespace std;
class Parent
{
public:
    Parent(string s)
    {
        cout << "Parent(string s): " << s << endl;
    }
};
class Child : public Parent
{
public:
    Child()
    {
        cout << "Child()" << endl;
    }
    
    Child(string s) : Parent(s)
    {
        cout << "Child(string s): " << s << endl;
    }
};
int main()
{
    Child c;
    
    Child cc("cc");
    
    return 0;
}我們先來分析下,在子類 Child 中,它定義的第一個構造函數顯然是隱式調用父類的構造函數。但是在父類的構造函數中,我們既沒有定義無參構造函數,也沒有定義默認參數的構造函數,所以這個隱式調用肯定會出錯。而第二個對象 cc 是進行顯示調用的,所以它不會報錯。我們來看看編譯結果

它報錯說第 19 行出錯,也就是子類的隱調用出錯了,下來我們在父類中通過一個無參構造函數,來看看編譯是否還會出錯呢

我們看到編譯通過了,并且也完美運行。我們來說說子類對象的構造規則:a> 子類對象在創建時會首先調用父類的構造函數;b> 先執行父類的構造函數再執行子類的構造函數;c> 父類構造函數可以被隱式調用或者顯示調用。那么子類對象的創建時構造函數的調用又有什么順序呢?1、調用父類的構造函數;2、調用成員變量的構造函數;3、調用類自身的構造函數。對此,有唐長老總結的一個口訣心法:先父母,后客人,再自己。
下來我們通過編程來看看子類創建時構造函數的執行順序
#include <iostream>
#include <string>
using namespace std;
class Object
{
    string ms;
public:
    Object(string s)
    {
        ms  = s;
        
        cout << "Object(string s): " << ms << endl;
    }
};
class Parent : public Object
{
    string ms;
public:
    Parent() : Object("Default")
    {
        ms = "Default";
    
        cout << "Parent()" << endl;
    }
    Parent(string s) : Object(s)
    {
        ms = s;
    
        cout << "Parent(string s): " << s << endl;
    }
};
class Child : public Parent
{
    Object mOb1;
    Object mOb2;
    string ms;
public:
    Child() : mOb1("Default 1"), mOb2("Default 2")
    {
        ms = "Default";
    
        cout << "Child()" << endl;
    }
    
    Child(string s) : Parent(s), mOb1(s + " 1"), mOb2(s + " 2")
    {
        ms = s;
        
        cout << "Child(string s): " << s << endl;
    }
};
int main()
{
    Child c;
    
    // c output:
    //   Object(string s): Default
    //   Parent()
    //   Object(string s): Default 1
    //   Object(string s): Default 2
    //   Child()
    
    cout << endl;
    
    Child cc("cc");
    
    // cc output:
    //   Object(string s): Default
    //   Parent(string s) : cc
    //   Object(string s): cc 1
    //   Object(string s): cc 2
    //   Child(string s): cc
    
    return 0;
}我們來分析下,類Child c 創建時首先會隱式調用它的父類構造函數 Parent() : Object("Default"),而 Parent 創建時會先調用它的父類 Object 的構造函數 Object("Default")。再來調用成員對象 mOb1 和 mOb2 的構造函數 mOb1("Default 1"), mOb2("Default 2"),最后調用自己的構造函數 Child()。所以最后打印的應該和我們程序中寫的是一致的。再來看看對象 cc 的創建過程,因為它是顯示調用,所以會調用構造函數 Parent(s) ,而 Parent 的父類 Object 也會調用構造函數 Object(string s) 。額庵后調用成員對象 mOb1 和 mOb2 的構造函數 mOb1(s + "1"), mOb2(s + "2"),最后調用自己的構造函數 Child(string s)。打印的應該也和我們在程序中寫的一致。我們來看編譯結果

結果和我們分析的是一致的。那么再來看看析構函數的調用順序,它跟構造函數的順序剛好相反:1、執行自身的析構函數;2、執行成員變量的析構函數;3、執行父類的析構函數。依舊是在上面的程序基礎之上,來看看析構函數的執行順序。
#include <iostream>
#include <string>
using namespace std;
class Object
{
    string ms;
public:
    Object(string s)
    {
        ms  = s;
        
        cout << "Object(string s): " << ms << endl;
    }
    
    ~Object()
    {
        cout << "~Object() : " << ms << endl;
    }
};
class Parent : public Object
{
    string ms;
public:
    Parent() : Object("Default")
    {
        ms = "Default";
    
        cout << "Parent()" << endl;
    }
    Parent(string s) : Object(s)
    {
        ms = s;
    
        cout << "Parent(string s): " << s << endl;
    }
    
    ~Parent()
    {
        cout << "~Parent() : " << ms << endl;
    }
};
class Child : public Parent
{
    Object mOb1;
    Object mOb2;
    string ms;
public:
    Child() : mOb1("Default 1"), mOb2("Default 2")
    {
        ms = "Default";
    
        cout << "Child()" << endl;
    }
    
    Child(string s) : Parent(s), mOb1(s + " 1"), mOb2(s + " 2")
    {
        ms = s;
        
        cout << "Child(string s): " << s << endl;
    }
    
    ~Child()
    {
        cout << "~Child() : " << ms << endl;
    }
};
int main()
{
    Child cc("cc");
    
    return 0;
}我們來看看編譯結果

感謝各位的閱讀,以上就是“c++繼承中的構造與析構方法是什么”的內容了,經過本文的學習后,相信大家對c++繼承中的構造與析構方法是什么這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是創新互聯,小編將為大家推送更多相關知識點的文章,歡迎關注!
另外有需要云服務器可以了解下創新互聯scvps.cn,海內外云服務器15元起步,三天無理由+7*72小時售后在線,公司持有idc許可證,提供“云服務器、裸金屬服務器、高防服務器、香港服務器、美國服務器、虛擬主機、免備案服務器”等云主機租用服務以及企業上云的綜合解決方案,具有“安全穩定、簡單易用、服務可用性高、性價比高”等特點與優勢,專為企業上云打造定制,能夠滿足用戶豐富、多元化的應用場景需求。
                本文題目:c++繼承中的構造與析構方法是什么-創新互聯
                
                文章轉載:http://www.yijiale78.com/article10/dpjpgo.html
            
成都網站建設公司_創新互聯,為您提供企業網站制作、微信公眾號、軟件開發、網站內鏈、用戶體驗、移動網站建設
聲明:本網站發布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網站立場,如需處理請聯系客服。電話:028-86922220;郵箱:631063699@qq.com。內容未經允許不得轉載,或轉載時需注明來源: 創新互聯
