C++11中的default函數(shù)使用
對(duì)于C++ 11標(biāo)準(zhǔn)中支持的default函數(shù),編譯器會(huì)為其自動(dòng)生成默認(rèn)的函數(shù)定義體,從而獲得更高的代碼執(zhí)行效率,也可免除程序員手動(dòng)定義該函數(shù)的工作量。
C++的類有四類特殊成員函數(shù),它們分別是:
- 默認(rèn)構(gòu)造函數(shù)
- 析構(gòu)函數(shù)
- 拷貝構(gòu)造函數(shù)
- 拷貝賦值運(yùn)算符
這些類的特殊成員函數(shù)負(fù)責(zé)創(chuàng)建、初始化、銷毀,或者拷貝類的對(duì)象,如果程序員沒(méi)有顯式地為一個(gè)類定義某個(gè)特殊成員函數(shù),而又需要用到該特殊成員函數(shù)時(shí),則編譯器會(huì)隱式的為這個(gè)類生成一個(gè)默認(rèn)的特殊成員函數(shù)。例如:
清單 1
class X{
private:
int a;
};
X x;
在清單 1 中,程序員并沒(méi)有定義類 X 的默認(rèn)構(gòu)造函數(shù),但是在創(chuàng)建類 X 的對(duì)象 x 的時(shí)候,又需要用到類 X 的默認(rèn)構(gòu)造函數(shù),此時(shí),編譯器會(huì)隱式的為類 X 生成一個(gè)默認(rèn)構(gòu)造函數(shù)。該自動(dòng)生成的默認(rèn)構(gòu)造函數(shù)沒(méi)有參數(shù),包含一個(gè)空的函數(shù)體,即 X::X(){ }。雖然自動(dòng)生成的默認(rèn)構(gòu)造函數(shù)僅有一個(gè)空函數(shù)體,但是它仍可用來(lái)成功創(chuàng)建類 X 的對(duì)象 x,清單 1 也可以編譯通過(guò)。
但是,如果程序員為類 X 顯式的自定義了非默認(rèn)構(gòu)造函數(shù),卻沒(méi)有定義默認(rèn)構(gòu)造函數(shù)的時(shí)候,清單 2 將會(huì)出現(xiàn)編譯錯(cuò)誤:
清單 2
class X{
public:
X(int i){
a = i;
}
private:
int a;
};
X x; // 錯(cuò)誤 , 默認(rèn)構(gòu)造函數(shù) X::X() 不存在
清單 2 編譯出錯(cuò)的原因在于類 X 已經(jīng)有了用戶自定義的構(gòu)造函數(shù),所以編譯器將不再會(huì)為它隱式的生成默認(rèn)構(gòu)造函數(shù)。如果需要用到默認(rèn)構(gòu)造函數(shù)來(lái)創(chuàng)建類的對(duì)象時(shí),程序員必須自己顯式的定義默認(rèn)構(gòu)造函數(shù)。例如:
清單 3
class X{
public:
X(){}; // 手動(dòng)定義默認(rèn)構(gòu)造函數(shù)
X(int i){
a = i;
}
private:
int a;
};
X x; // 正確,默認(rèn)構(gòu)造函數(shù) X::X() 存在
從清單 3 可以看出,原本期望編譯器自動(dòng)生成的默認(rèn)構(gòu)造函數(shù)需要程序員手動(dòng)編寫了,即程序員的工作量加大了。此外,手動(dòng)編寫的默認(rèn)構(gòu)造函數(shù)的代碼執(zhí)行效率比編譯器自動(dòng)生成的默認(rèn)構(gòu)造函數(shù)低。類的其它幾類特殊成員函數(shù)也和默認(rèn)構(gòu)造函數(shù)一樣,當(dāng)存在用戶自定義的特殊成員函數(shù)時(shí),編譯器將不會(huì)隱式的自動(dòng)生成默認(rèn)特殊成員函數(shù),而需要程序員手動(dòng)編寫,加大了程序員的工作量。類似的,手動(dòng)編寫的特殊成員函數(shù)的代碼執(zhí)行效率比編譯器自動(dòng)生成的特殊成員函數(shù)低。
為了解決如清單 3 所示的兩個(gè)問(wèn)題:
減輕程序員的編程工作量;
- 獲得編譯器自動(dòng)生成的默認(rèn)特殊成員函數(shù)的高的代碼執(zhí)行效率
- C++11 標(biāo)準(zhǔn)引入了一個(gè)新特性:default函數(shù)。程序員只需在函數(shù)聲明后加上=default;,就可將該函數(shù)聲明為 default 函數(shù),編譯器將為顯式聲明的 default 函數(shù)自動(dòng)生成函數(shù)體。例如:
清單 4
class X{
public:
X()= default;
X(int i){
a = i;
}
private:
int a;
};
X x;
在清單 4 中,編譯器會(huì)自動(dòng)生成默認(rèn)構(gòu)造函數(shù) X::X(){},該函數(shù)可以比用戶自己定義的默認(rèn)構(gòu)造函數(shù)獲得更高的代碼效率。
Default 函數(shù)特性僅適用于類的特殊成員函數(shù),且該特殊成員函數(shù)沒(méi)有默認(rèn)參數(shù)。例如:
清單 5
class X {
public:
int f() = default; // 錯(cuò)誤 , 函數(shù) f() 非類 X 的特殊成員函數(shù)
X(int) = default; // 錯(cuò)誤 , 構(gòu)造函數(shù) X(int, int) 非 X 的特殊成員函數(shù)
X(int = 1) = default; // 錯(cuò)誤 , 默認(rèn)構(gòu)造函數(shù) X(int=1) 含有默認(rèn)參數(shù)
};
Default 函數(shù)既可以在類體里(inline)定義,也可以在類體外(out-of-line)定義。例如:
清單 6
class X{
public:
X() = default; //Inline default 默認(rèn)構(gòu)造函數(shù)
X(const X&);
X& operator = (const X&);
~X() = default; //Inline default 析構(gòu)函數(shù)
};
X::X(const X&) = default; //Out-of-line default 拷貝構(gòu)造函數(shù)
X& X::operator = (const X&) = default; //Out-of-line default
// 拷貝賦值操作符
在 C++ 代碼編譯過(guò)程中,如果程序員沒(méi)有為類 X 定義析構(gòu)函數(shù),但是在銷毀類 X 對(duì)象的時(shí)候又需要調(diào)用類 X 的析構(gòu)函數(shù)時(shí),編譯器會(huì)自動(dòng)隱式的為該類生成一個(gè)析構(gòu)函數(shù)。該自動(dòng)生成的析構(gòu)函數(shù)沒(méi)有參數(shù),包含一個(gè)空的函數(shù)體,即 X::~X(){ }。例如:
清單 7
class X {
private:
int x;
};
class Y: public X {
private:
int y;
};
int main(){
X* x = new Y;
delete x;
}
在清單 7 中,程序員沒(méi)有為基類 X 和派生類 Y 定義析構(gòu)函數(shù),當(dāng)在主函數(shù)內(nèi) delete 基類指針 x 的時(shí)候,需要調(diào)用基類的析構(gòu)函數(shù)。于是,編譯器會(huì)隱式自動(dòng)的為類 X 生成一個(gè)析構(gòu)函數(shù),從而可以成功的銷毀 x 指向的派生類對(duì)象中的基類子對(duì)象(即 int 型成員變量 x)。
但是,這段代碼存在內(nèi)存泄露的問(wèn)題,當(dāng)利用 delete 語(yǔ)句刪除指向派生類對(duì)象的指針 x 時(shí),系統(tǒng)調(diào)用的是基類的析構(gòu)函數(shù),而非派生類 Y 類的析構(gòu)函數(shù),因此,編譯器無(wú)法析構(gòu)派生類的 int 型成員變量 y。
因此,一般情況下我們需要將基類的析構(gòu)函數(shù)定義為虛函數(shù),當(dāng)利用 delete 語(yǔ)句刪除指向派生類對(duì)象的基類指針時(shí),系統(tǒng)會(huì)調(diào)用相應(yīng)的派生類的析構(gòu)函數(shù)(實(shí)現(xiàn)多態(tài)性),從而避免內(nèi)存泄露。但是編譯器隱式自動(dòng)生成的析構(gòu)函數(shù)都是非虛函數(shù),這就需要由程序員手動(dòng)的為基類 X 定義虛析構(gòu)函數(shù),例如:
清單 8
class X {
public:
virtual ~X(){}; // 手動(dòng)定義虛析構(gòu)函數(shù)
private:
int x;
};
class Y: public X {
private:
int y;
};
int main(){
X* x = new Y;
delete x;
}
在清單 8 中,由于程序員手動(dòng)為基類 X 定義了虛析構(gòu)函數(shù),當(dāng)利用 delete 語(yǔ)句刪除指向派生類對(duì)象的基類指針 x 時(shí),系統(tǒng)會(huì)調(diào)用相應(yīng)的派生類 Y 的析構(gòu)函數(shù)(由編譯器隱式自動(dòng)生成)以及基類 X 的析構(gòu)函數(shù),從而將派生類對(duì)象完整的銷毀,可以避免內(nèi)存泄露。
但是,在清單 8 中,程序員需要手動(dòng)的編寫基類的虛構(gòu)函數(shù)的定義(哪怕函數(shù)體是空的),增加了程序員的編程工作量。更值得一提的是,手動(dòng)定義的析構(gòu)函數(shù)的代碼執(zhí)行效率要低于編譯器自動(dòng)生成的析構(gòu)函數(shù)。
為了解決上述問(wèn)題,我們可以將基類的虛析構(gòu)函數(shù)聲明為 default 函數(shù),這樣就可以顯式的指定編譯器為該函數(shù)自動(dòng)生成函數(shù)體。例如:
清單 9
class X {
public:
virtual ~X()= default; // 編譯器自動(dòng)生成 default 函數(shù)定義體
private:
int x;
};
class Y: public X {
private:
int y;
};
int main(){
X* x = new Y;
delete x;
}
到此這篇關(guān)于C++11中的default函數(shù)使用的文章就介紹到這了,更多相關(guān)C++11 default函數(shù)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
c語(yǔ)言string.h頭文件中所有函數(shù)示例詳解
這篇文章詳細(xì)介紹了C語(yǔ)言標(biāo)準(zhǔn)庫(kù)中的字符串和內(nèi)存操作函數(shù),以str開(kāi)頭的字符串處理函數(shù)和以mem開(kāi)頭的內(nèi)存處理函數(shù),每種函數(shù)都有詳細(xì)的原型、功能描述和示例代碼,需要的朋友可以參考下2024-11-11
C++控制臺(tái)實(shí)現(xiàn)隨機(jī)生成路徑迷宮游戲
這篇文章主要為大家詳細(xì)介紹了C++控制臺(tái)實(shí)現(xiàn)隨機(jī)生成路徑迷宮游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-05-05
c++ 網(wǎng)絡(luò)庫(kù)asio的優(yōu)勢(shì)
這篇文章主要介紹了c++ 網(wǎng)絡(luò)庫(kù)asio的優(yōu)勢(shì),幫助大家更好的利用c++開(kāi)發(fā)服務(wù)端程序,感興趣的朋友可以了解下2020-10-10
使用C語(yǔ)言實(shí)現(xiàn)交換整數(shù)的奇數(shù)位和偶數(shù)位
在C語(yǔ)言中,要交換一個(gè)整數(shù)的二進(jìn)制位中的奇數(shù)位和偶數(shù)位,重點(diǎn)需要理解位操作,當(dāng)我們談?wù)摱M(jìn)制位的奇數(shù)位和偶數(shù)位時(shí),我們是指從右到左數(shù)的位置,本文給大家介紹了使用C語(yǔ)言代碼實(shí)現(xiàn)將一個(gè)整數(shù)的奇數(shù)位和偶數(shù)位交換,需要的朋友可以參考下2025-03-03
Opencv實(shí)現(xiàn)聯(lián)合雙邊濾波
這篇文章主要為大家詳細(xì)介紹了Opencv實(shí)現(xiàn)聯(lián)合雙邊濾波,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-10-10
C++中的std::funture和std::promise實(shí)例詳解
在線程池中獲取線程執(zhí)行函數(shù)的返回值時(shí),通常使用 std::future 而不是 std::promise 來(lái)傳遞返回值,這篇文章主要介紹了C++中的std::funture和std::promise實(shí)例詳解,需要的朋友可以參考下2024-05-05
Qt使用QPainter實(shí)現(xiàn)自定義圓形進(jìn)度條
這篇文章主要介紹了Qt如何使用QPainter實(shí)現(xiàn)自定義圓形進(jìn)度條功能,文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)Qt有一定的幫助,需要的可以參考一下2022-06-06
提高C++程序運(yùn)行效率的10個(gè)簡(jiǎn)單方法
這篇文章主要介紹了提高C++程序運(yùn)行效率的10個(gè)簡(jiǎn)單方法,包括了循環(huán)、變量、繼承等等應(yīng)用的技巧,非常具有實(shí)用價(jià)值,需要的朋友可以參考下2014-09-09

