C++11委托構(gòu)造函數(shù)和繼承構(gòu)造函數(shù)的實現(xiàn)
引言
在C++11標(biāo)準(zhǔn)中,引入了委托構(gòu)造函數(shù)和繼承構(gòu)造函數(shù)這兩個重要的特性。這些特性不僅提升了代碼的性能,還增強了代碼的可讀性和可維護性。對于初學(xué)者來說,理解和掌握這些特性是邁向高級C++編程的關(guān)鍵一步。本文將詳細(xì)介紹委托構(gòu)造函數(shù)和繼承構(gòu)造函數(shù)的基本概念、使用方法以及實際應(yīng)用場景,幫助你從入門到精通。
一、委托構(gòu)造函數(shù)
1.1 委托構(gòu)造函數(shù)的定義與作用
委托構(gòu)造函數(shù)是C++11引入的一個特性,它允許一個構(gòu)造函數(shù)調(diào)用同一個類中的另一個構(gòu)造函數(shù)來完成對象的初始化。這種特性可以減少代碼冗余,提高代碼的可維護性,同時也使得代碼結(jié)構(gòu)更加清晰。例如,在一個類中可能有多個構(gòu)造函數(shù),它們之間存在一些重復(fù)的初始化代碼,使用委托構(gòu)造函數(shù)可以避免這些重復(fù)代碼的出現(xiàn)。
1.2 委托構(gòu)造函數(shù)的語法
委托構(gòu)造函數(shù)的語法格式如下:
class MyClass { public: // 目標(biāo)構(gòu)造函數(shù) MyClass(int param1, int param2) { // 構(gòu)造函數(shù)的具體實現(xiàn) } // 委托構(gòu)造函數(shù) MyClass(int param) : MyClass(param, 0) { // 委托給另一個構(gòu)造函數(shù)完成初始化 } };
在上述代碼中,第一個構(gòu)造函數(shù)接受兩個參數(shù),而第二個構(gòu)造函數(shù)只接受一個參數(shù)。第二個構(gòu)造函數(shù)使用了初始化列表的方式,通過委托給第一個構(gòu)造函數(shù)來完成對象的初始化。
1.3 委托構(gòu)造函數(shù)的使用示例
下面通過一個具體的例子來詳細(xì)解析委托構(gòu)造函數(shù)的使用:
#include <iostream> using namespace std; class Test { public: Test() {}; Test(int max) { this->m_max = max > 0 ? max : 100; } Test(int max, int min) : Test(max) { this->m_min = min > 0 && min < max ? min : 1; } Test(int max, int min, int mid) : Test(max, min) { this->m_middle = mid < max && mid > min ? mid : 50; } int m_min; int m_max; int m_middle; }; int main() { Test t(90, 30, 60); cout << "min: " << t.m_min << ", middle: " << t.m_middle << ", max: " << t.m_max << endl; return 0; }
在這個例子中,Test(int max, int min)
構(gòu)造函數(shù)委托給 Test(int max)
構(gòu)造函數(shù),Test(int max, int min, int mid)
構(gòu)造函數(shù)委托給 Test(int max, int min)
構(gòu)造函數(shù),這樣可以避免在多個構(gòu)造函數(shù)中重復(fù)初始化 m_max
和 m_min
。
1.4 委托構(gòu)造函數(shù)的注意事項
- 避免形成閉環(huán):委托構(gòu)造函數(shù)的鏈?zhǔn)秸{(diào)用不能形成一個閉環(huán)(死循環(huán)),否則會在運行期拋異常。例如:
class MyClass { public: MyClass(int param1) : MyClass(param1, 0) { // 委托給另一個構(gòu)造函數(shù)完成初始化 } MyClass(int param1, int param2) : MyClass(param1) { // 錯誤:形成了閉環(huán) } };
- 多層鏈?zhǔn)秸{(diào)用建議寫在初始化列表中:如果要進行多層構(gòu)造函數(shù)的鏈?zhǔn)秸{(diào)用,建議將構(gòu)造函數(shù)的調(diào)用寫在初始列表中而不是函數(shù)體內(nèi)部,否則編譯器會提示形參的重復(fù)定義。例如:
class Test { public: Test(int max) { this->m_max = max > 0 ? max : 100; } Test(int max, int min) { Test(max); // 錯誤,編譯器會報錯,提示形參max被重復(fù)定義 this->m_min = min > 0 && min < max ? min : 1; } };
- 避免重復(fù)初始化變量:在初始化列表中調(diào)用了委托構(gòu)造函數(shù)初始化某個類成員變量之后,就不能在初始化列表中再次初始化這個變量了。例如:
class Test { public: Test(int max, int min) : Test(max), m_max(max) { // 錯誤,使用了委托構(gòu)造函數(shù)就不能再次m_max初始化了 this->m_min = min > 0 && min < max ? min : 1; } };
二、繼承構(gòu)造函數(shù)
2.1 繼承構(gòu)造函數(shù)的定義與作用
在C++11之前,如果基類有多個構(gòu)造函數(shù),派生類需要為自己需要用到的每一個基類構(gòu)造函數(shù)編寫對應(yīng)的構(gòu)造函數(shù),即使這些派生類構(gòu)造函數(shù)只是簡單地將參數(shù)傳遞給基類構(gòu)造函數(shù)。這不僅增加了代碼量,也提高了維護成本。繼承構(gòu)造函數(shù)允許派生類繼承基類的所有構(gòu)造函數(shù),從而無需在派生類中顯式定義這些構(gòu)造函數(shù)。這樣做可以顯著減少代碼重復(fù),使得派生類的編寫更加簡潔明了。
2.2 繼承構(gòu)造函數(shù)的語法
繼承構(gòu)造函數(shù)的語法格式如下:
class Base { public: Base() { // 默認(rèn)構(gòu)造函數(shù)的實現(xiàn) } Base(int value) { // 帶參數(shù)的構(gòu)造函數(shù)實現(xiàn) } }; class Derived : public Base { public: using Base::Base; // 繼承基類的所有構(gòu)造函數(shù) };
在這個示例中,通過在派生類中使用 using Base::Base;
語句,Derived
類自動繼承了 Base
類的所有構(gòu)造函數(shù)。不需要在 Derived
類中顯式定義這些構(gòu)造函數(shù),就可以像使用 Base
類的構(gòu)造函數(shù)那樣使用它們來初始化 Derived
類的對象。
2.3 繼承構(gòu)造函數(shù)的使用示例
下面通過一個具體的例子來詳細(xì)解析繼承構(gòu)造函數(shù)的使用:
#include <iostream> #include <string> using namespace std; class Base { public: Base(int i) : m_i(i) { } Base(int i, double j) : m_i(i), m_j(j) { } Base(int i, double j, string k) : m_i(i), m_j(j), m_k(k) { } int m_i; double m_j; string m_k; }; class Child : public Base { public: using Base::Base; }; int main() { Child c(520, 13.14, "i love you"); cout << "int: " << c.m_i << ", double: " << c.m_j << ", string: " << c.m_k << endl; return 0; }
通過測試代碼可以看出,在子類中初始化從基類繼承的類成員,使用繼承構(gòu)造函數(shù)可以避免在子類中重新定義和基類一致的構(gòu)造函數(shù),使得代碼更加精簡。
2.4 繼承構(gòu)造函數(shù)的注意事項
- 同名構(gòu)造函數(shù)沖突:如果從多個基類中繼承了相同的構(gòu)造函數(shù)(即形參列表完全相同),則程序?qū)a(chǎn)生錯誤。例如:
struct Base1 { Base1() = default; Base1(const std::string&); Base1(std::shared_ptr<int>); }; struct Base2 { Base2() = default; Base2(const std::string&); Base2(int); }; // 錯誤: D1 試圖從兩個基類中都繼承D1::D1(const string&) struct D1 : public Base1, public Base2 { using Base1::Base1; //從 Base1 繼承構(gòu)造函數(shù) using Base2::Base2; //從 Base2 繼承構(gòu)造函數(shù) };
在這種情況下,派生類必須為該構(gòu)造函數(shù)定義它自己的版本:
struct D2 : public Base1, public Base2 { using Base1::Base1; //從 Base1 繼承構(gòu)造函數(shù) using Base2::Base2; //從 Base2 繼承構(gòu)造函數(shù) // D2 必須自定義一個接受 string 的構(gòu)造函數(shù) D2(const string& s) : Base1(s), Base2(s) { } D2() = default; // 一旦 D2 定義了它自己的構(gòu)造函數(shù),則必須出現(xiàn) };
- 默認(rèn)實參不繼承:當(dāng)一個基類構(gòu)造函數(shù)含有默認(rèn)實參時,這些實參并不會被繼承。相反,派生類將獲得多個繼承的構(gòu)造函數(shù),其中每個構(gòu)造函數(shù)分別省略掉一個含有默認(rèn)實參的形參。例如,如果基類有一個接受兩個形參的構(gòu)造函數(shù),其中第二個形參含有默認(rèn)實參,則派生類將獲得兩個構(gòu)造函數(shù):一個構(gòu)造函數(shù)接受兩個形參(沒有默認(rèn)實參);另一個構(gòu)造函數(shù)只接受一個形參,它對應(yīng)于基類中最左側(cè)的沒有默認(rèn)值的那個形參。
三、總結(jié)
委托構(gòu)造函數(shù)和繼承構(gòu)造函數(shù)是C++11中非常強大的特性,它們?yōu)镃++程序員提供了更多的編程選擇和優(yōu)化機會。通過使用委托構(gòu)造函數(shù),我們可以減少代碼冗余,提高代碼的可維護性;而繼承構(gòu)造函數(shù)則可以簡化派生類構(gòu)造函數(shù)的編寫,提高代碼的復(fù)用性。在實際編程中,合理運用這些特性可以讓我們的代碼更加高效、安全和易于理解。希望本文能夠幫助你更好地理解和掌握C++11中的委托構(gòu)造函數(shù)和繼承構(gòu)造函數(shù),從而提升你的C++編程水平。
到此這篇關(guān)于C++11委托構(gòu)造函數(shù)和繼承構(gòu)造函數(shù):從入門到精通的文章就介紹到這了,更多相關(guān)C++11委托構(gòu)造函數(shù)和繼承構(gòu)造函數(shù)內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- C++類成員構(gòu)造函數(shù)和析構(gòu)函數(shù)順序示例詳細(xì)講解
- 深入解析C++中的構(gòu)造函數(shù)和析構(gòu)函數(shù)
- C++中拷貝構(gòu)造函數(shù)的總結(jié)詳解
- c++類構(gòu)造函數(shù)詳解
- 深入C++中構(gòu)造函數(shù)、拷貝構(gòu)造函數(shù)、賦值操作符、析構(gòu)函數(shù)的調(diào)用過程總結(jié)
- c++中拷貝構(gòu)造函數(shù)的參數(shù)類型必須是引用
- 解析C++中構(gòu)造函數(shù)的默認(rèn)參數(shù)和構(gòu)造函數(shù)的重載
- C++中拷貝構(gòu)造函數(shù)的應(yīng)用詳解
相關(guān)文章
QT基于TCP實現(xiàn)網(wǎng)絡(luò)聊天室程序
這篇文章主要為大家詳細(xì)介紹了QT基于TCP實現(xiàn)網(wǎng)絡(luò)聊天室程序,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2022-08-08數(shù)據(jù)結(jié)構(gòu) 數(shù)組順序存儲詳細(xì)介紹
這篇文章主要介紹了數(shù)據(jù)結(jié)構(gòu) 數(shù)組順序存儲詳細(xì)介紹的相關(guān)資料,需要的朋友可以參考下2017-05-05C語言中的typedef、#define、const特點和用法介紹
在C 語言中,typedef、#define和const都用于定義常量和簡化代碼,但它們的用途和工作方式有顯著區(qū)別,下面詳細(xì)講解這三者的特點和用法,感興趣的朋友一起看看吧2024-08-08C++實現(xiàn)中綴表達(dá)式轉(zhuǎn)后綴表達(dá)式
這篇文章主要為大家詳細(xì)介紹了C++實現(xiàn)中綴表達(dá)式轉(zhuǎn)后綴表達(dá)式,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2020-04-04