這篇文章主要講解了“c++繼承中的構(gòu)造與析構(gòu)方法是什么”,文中的講解內(nèi)容簡(jiǎn)單清晰,易于學(xué)習(xí)與理解,下面請(qǐng)大家跟著小編的思路慢慢深入,一起來研究和學(xué)習(xí)“c++繼承中的構(gòu)造與析構(gòu)方法是什么”吧!
成都創(chuàng)新互聯(lián)公司-專業(yè)網(wǎng)站定制、快速模板網(wǎng)站建設(shè)、高性價(jià)比紅橋網(wǎng)站開發(fā)、企業(yè)建站全套包干低至880元,成熟完善的模板庫,直接使用。一站式紅橋網(wǎng)站制作公司更省心,省錢,快速模板網(wǎng)站建設(shè)找我們,業(yè)務(wù)覆蓋紅橋地區(qū)。費(fèi)用合理售后完善,十載實(shí)體公司更值得信賴。
我們思考下這個(gè)問題:如何初始化父類成員?父類構(gòu)造函數(shù)和子類構(gòu)造函數(shù)有何關(guān)系呢?在子類中可以定義構(gòu)造函數(shù),子類構(gòu)造函數(shù)必須對(duì)繼承而來的成員進(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)用時(shí)在子類構(gòu)造函數(shù)后加上父類構(gòu)造函數(shù),如下所示
下來我們就對(duì)子類的構(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è)構(gòu)造函數(shù)顯然是隱式調(diào)用父類的構(gòu)造函數(shù)。但是在父類的構(gòu)造函數(shù)中,我們既沒有定義無參構(gòu)造函數(shù),也沒有定義默認(rèn)參數(shù)的構(gòu)造函數(shù),所以這個(gè)隱式調(diào)用肯定會(huì)出錯(cuò)。而第二個(gè)對(duì)象 cc 是進(jìn)行顯示調(diào)用的,所以它不會(huì)報(bào)錯(cuò)。我們來看看編譯結(jié)果
它報(bào)錯(cuò)說第 19 行出錯(cuò),也就是子類的隱調(diào)用出錯(cuò)了,下來我們?cè)诟割愔型ㄟ^一個(gè)無參構(gòu)造函數(shù),來看看編譯是否還會(huì)出錯(cuò)呢
我們看到編譯通過了,并且也完美運(yùn)行。我們來說說子類對(duì)象的構(gòu)造規(guī)則:a> 子類對(duì)象在創(chuàng)建時(shí)會(huì)首先調(diào)用父類的構(gòu)造函數(shù);b> 先執(zhí)行父類的構(gòu)造函數(shù)再執(zhí)行子類的構(gòu)造函數(shù);c> 父類構(gòu)造函數(shù)可以被隱式調(diào)用或者顯示調(diào)用。那么子類對(duì)象的創(chuàng)建時(shí)構(gòu)造函數(shù)的調(diào)用又有什么順序呢?1、調(diào)用父類的構(gòu)造函數(shù);2、調(diào)用成員變量的構(gòu)造函數(shù);3、調(diào)用類自身的構(gòu)造函數(shù)。對(duì)此,有唐長老總結(jié)的一個(gè)口訣心法:先父母,后客人,再自己。
下來我們通過編程來看看子類創(chuàng)建時(shí)構(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)建時(shí)首先會(huì)隱式調(diào)用它的父類構(gòu)造函數(shù) Parent() : Object("Default"),而 Parent 創(chuàng)建時(shí)會(huì)先調(diào)用它的父類 Object 的構(gòu)造函數(shù) Object("Default")。再來調(diào)用成員對(duì)象 mOb1 和 mOb2 的構(gòu)造函數(shù) mOb1("Default 1"), mOb2("Default 2"),最后調(diào)用自己的構(gòu)造函數(shù) Child()。所以最后打印的應(yīng)該和我們程序中寫的是一致的。再來看看對(duì)象 cc 的創(chuàng)建過程,因?yàn)樗秋@示調(diào)用,所以會(huì)調(diào)用構(gòu)造函數(shù) Parent(s) ,而 Parent 的父類 Object 也會(huì)調(diào)用構(gòu)造函數(shù) Object(string s) 。額庵后調(diào)用成員對(duì)象 mOb1 和 mOb2 的構(gòu)造函數(shù) mOb1(s + "1"), mOb2(s + "2"),最后調(diào)用自己的構(gòu)造函數(shù) Child(string s)。打印的應(yīng)該也和我們?cè)诔绦蛑袑懙囊恢?。我們來看編譯結(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í)后,相信大家對(duì)c++繼承中的構(gòu)造與析構(gòu)方法是什么這一問題有了更深刻的體會(huì),具體使用情況還需要大家實(shí)踐驗(yàn)證。這里是創(chuàng)新互聯(lián),小編將為大家推送更多相關(guān)知識(shí)點(diǎn)的文章,歡迎關(guān)注!