本文將介紹禁止編譯器自動生成某些函數(shù)的2種方法,及在某些場景下(例如嵌入式編程中)计福,禁止析構(gòu)函數(shù)給程序帶來的好處豌鹤。
還記得如何禁止默認(rèn)構(gòu)造函數(shù)嗎,即定義一個帶參數(shù)的構(gòu)造函數(shù)即可鸭廷,如下面的代碼將會編譯失敗
class OpenFile {
public:
// 定義一個帶參構(gòu)造函數(shù)
OpenFile(string filename) {/*...*/}
};
int main() {
OpenFile f; // error: no matching constructor for initialization of 'OpenFile'
}
除此之外枣抱,我們還可以顯示的禁止某些函數(shù)的定義
- 在 C++ 03 中,我們可以將這些函數(shù)聲明在
private
作用域中辆床,且不定義它們 - 在 C++ 11 中佳晶,提供了
delete
關(guān)鍵字來實現(xiàn)此功能
假設(shè)你有一個文件類 OpenFile
,你不希望這類對象互相復(fù)制佛吓,因為這會把文件寫亂宵晚,此時你可以禁止該類的復(fù)制構(gòu)造函數(shù)和賦值操作符,在 C++ 03 中维雇,你可以這樣做
class OpenFile {
private:
OpenFile(OpenFile& rhs);
OpenFile& operator=(const OpenFile& rhs);
}淤刃;
C++ 11中是這樣的
class OpenFile {
public:
OpenFile(OpenFile& rhs) = delete;
OpenFile& operator=(const OpenFile& rhs) = delete;
};
在某些情況下吱型,如果你不希望繼承來自基類的函數(shù)逸贾,你也可以這樣顯示聲明
class Base {
public:
void foo();
};
class Derived : public Base {
public:
void foo() = delete; // 不繼承 foo()
};
int main() {
Derived d;
d.foo(); // error: attempt to use a deleted function
}
禁止析構(gòu)函數(shù)
在嵌入式編程中,由于椊蛑停空間比較小的原因铝侵,我們會避開將一些大對象存儲在棧中,而選擇將他們存放在堆中触徐,棧中對象的特點是:當(dāng)對象離開局部空間(函數(shù)或程序塊)咪鲜,存儲在棧中的對象會自動釋放,對象的析構(gòu)函數(shù)會被調(diào)用撞鹉,此時疟丙,如果我們將對象的析構(gòu)函數(shù)定義在 private
域中,即禁止外部釋放對象鸟雏,就可以有效地保護對象不被存儲在棧中享郊。
當(dāng)然,存儲在堆中的對象還是要提供銷毀功能的孝鹊,你可以額外定義一個「自定義的析構(gòu)函數(shù)」炊琉,如下:
class BigBlock {
public:
BigBlock();
void destroyMe() {delete this;}
private:
~BigBlock() {/*...*/}
};
int main() {
BigBlock *b = new BigBlock();
b->destroyMe();
}
總結(jié),本文主要介紹了以下內(nèi)容
- C++ 11: f() = delete; 使用
delete
關(guān)鍵字 - C++ 03: 將函數(shù)聲明在
private
中又活,且不定義它 -
private
析構(gòu)函數(shù): stay out of stack.
參考: