這篇文章主要講解了“c++繼承中的構(gòu)造與析構(gòu)方法是什么”,文中的講解內(nèi)容簡單清晰,易于學(xué)習(xí)與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學(xué)習(xí)“c++繼承中的構(gòu)造與析構(gòu)方法是什么”吧!
站在用戶的角度思考問題,與客戶深入溝通,找到遂平網(wǎng)站設(shè)計與遂平網(wǎng)站推廣的解決方案,憑借多年的經(jīng)驗,讓設(shè)計與互聯(lián)網(wǎng)技術(shù)結(jié)合,創(chuàng)造個性化、用戶體驗好的作品,建站類型包括:成都網(wǎng)站設(shè)計、網(wǎng)站制作、企業(yè)官網(wǎng)、英文網(wǎng)站、手機(jī)端網(wǎng)站、網(wǎng)站推廣、申請域名、網(wǎng)頁空間、企業(yè)郵箱。業(yè)務(wù)覆蓋遂平地區(qū)。我們思考下這個問題:如何初始化父類成員?父類構(gòu)造函數(shù)和子類構(gòu)造函數(shù)有何關(guān)系呢?在子類中可以定義構(gòu)造函數(shù),子類構(gòu)造函數(shù)必須對繼承而來的成員進(jìn)行初始化:a> 直接通過初始化列表或者賦值的方式進(jìn)行初始化;b> 調(diào)用父類構(gòu)造函數(shù)進(jìn)行初始化。
下來我們來說說父類構(gòu)造函數(shù)在子類中的調(diào)用方式,分為兩種:a> 默認(rèn)調(diào)用:適用于無參構(gòu)造函數(shù)和使用默認(rèn)參數(shù)的構(gòu)造函數(shù);b> 顯示調(diào)用:通過初始化列表進(jìn)行調(diào)用,適用于所有父類構(gòu)造函數(shù)。那么隱式調(diào)用是在子類的構(gòu)造函數(shù)中啥都不加,顯示調(diào)用時在子類構(gòu)造函數(shù)后加上父類構(gòu)造函數(shù),如下所示
下來我們就對子類的構(gòu)造函數(shù)一探究竟
#include#include 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 中,它定義的第一個構(gòu)造函數(shù)顯然是隱式調(diào)用父類的構(gòu)造函數(shù)。但是在父類的構(gòu)造函數(shù)中,我們既沒有定義無參構(gòu)造函數(shù),也沒有定義默認(rèn)參數(shù)的構(gòu)造函數(shù),所以這個隱式調(diào)用肯定會出錯。而第二個對象 cc 是進(jìn)行顯示調(diào)用的,所以它不會報錯。我們來看看編譯結(jié)果
它報錯說第 19 行出錯,也就是子類的隱調(diào)用出錯了,下來我們在父類中通過一個無參構(gòu)造函數(shù),來看看編譯是否還會出錯呢
我們看到編譯通過了,并且也完美運行。我們來說說子類對象的構(gòu)造規(guī)則:a> 子類對象在創(chuàng)建時會首先調(diào)用父類的構(gòu)造函數(shù);b> 先執(zhí)行父類的構(gòu)造函數(shù)再執(zhí)行子類的構(gòu)造函數(shù);c> 父類構(gòu)造函數(shù)可以被隱式調(diào)用或者顯示調(diào)用。那么子類對象的創(chuàng)建時構(gòu)造函數(shù)的調(diào)用又有什么順序呢?1、調(diào)用父類的構(gòu)造函數(shù);2、調(diào)用成員變量的構(gòu)造函數(shù);3、調(diào)用類自身的構(gòu)造函數(shù)。對此,有唐長老總結(jié)的一個口訣心法:先父母,后客人,再自己。
下來我們通過編程來看看子類創(chuàng)建時構(gòu)造函數(shù)的執(zhí)行順序
#include#include 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 創(chuàng)建時首先會隱式調(diào)用它的父類構(gòu)造函數(shù) Parent() : Object("Default"),而 Parent 創(chuàng)建時會先調(diào)用它的父類 Object 的構(gòu)造函數(shù) Object("Default")。再來調(diào)用成員對象 mOb1 和 mOb2 的構(gòu)造函數(shù) mOb1("Default 1"), mOb2("Default 2"),最后調(diào)用自己的構(gòu)造函數(shù) Child()。所以最后打印的應(yīng)該和我們程序中寫的是一致的。再來看看對象 cc 的創(chuàng)建過程,因為它是顯示調(diào)用,所以會調(diào)用構(gòu)造函數(shù) Parent(s) ,而 Parent 的父類 Object 也會調(diào)用構(gòu)造函數(shù) Object(string s) 。額庵后調(diào)用成員對象 mOb1 和 mOb2 的構(gòu)造函數(shù) mOb1(s + "1"), mOb2(s + "2"),最后調(diào)用自己的構(gòu)造函數(shù) Child(string s)。打印的應(yīng)該也和我們在程序中寫的一致。我們來看編譯結(jié)果
結(jié)果和我們分析的是一致的。那么再來看看析構(gòu)函數(shù)的調(diào)用順序,它跟構(gòu)造函數(shù)的順序剛好相反:1、執(zhí)行自身的析構(gòu)函數(shù);2、執(zhí)行成員變量的析構(gòu)函數(shù);3、執(zhí)行父類的析構(gòu)函數(shù)。依舊是在上面的程序基礎(chǔ)之上,來看看析構(gòu)函數(shù)的執(zhí)行順序。
#include#include 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; }
我們來看看編譯結(jié)果
感謝各位的閱讀,以上就是“c++繼承中的構(gòu)造與析構(gòu)方法是什么”的內(nèi)容了,經(jīng)過本文的學(xué)習(xí)后,相信大家對c++繼承中的構(gòu)造與析構(gòu)方法是什么這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是創(chuàng)新互聯(lián),小編將為大家推送更多相關(guān)知識點的文章,歡迎關(guān)注!
另外有需要云服務(wù)器可以了解下創(chuàng)新互聯(lián)scvps.cn,海內(nèi)外云服務(wù)器15元起步,三天無理由+7*72小時售后在線,公司持有idc許可證,提供“云服務(wù)器、裸金屬服務(wù)器、高防服務(wù)器、香港服務(wù)器、美國服務(wù)器、虛擬主機(jī)、免備案服務(wù)器”等云主機(jī)租用服務(wù)以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡單易用、服務(wù)可用性高、性價比高”等特點與優(yōu)勢,專為企業(yè)上云打造定制,能夠滿足用戶豐富、多元化的應(yīng)用場景需求。