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)文章
C++下如何將TensorFlow模型封裝成DLL供C#調(diào)用
這篇文章主要介紹了C++下如何將TensorFlow模型封裝成DLL供C#調(diào)用問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-11-11
c++ 頭文件<cwchar>中常見函數(shù)的實現(xiàn)代碼
本文記錄了c++ 頭文件<cwchar>中常見函數(shù)的實現(xiàn),本文結(jié)合實例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友參考下吧2023-12-12
c語言獲取當(dāng)前工作路徑的實現(xiàn)代碼(windows/linux)
這篇文章主要介紹了c語言獲取當(dāng)前工作路徑的實現(xiàn)代碼(windows/linux),需要的朋友可以參考下2017-09-09
C++初學(xué)者之根據(jù)輸入的任何一個正整數(shù),輸出可能被表示的連續(xù)正整數(shù)
這篇文章主要介紹了C++初學(xué)者之根據(jù)輸入的任何一個正整數(shù),輸出可能被表示的連續(xù)正整數(shù)的相關(guān)資料,需要的朋友可以參考下2016-03-03

