C++中如果沒有顯式定義類的建構函式和賦值運算子,編譯器會自動生成對應的函式,但是對於一些含有指標成員變數的類,自動生成的成員函式只會進行淺複製,會導致動態申請的記憶體在物件析構的時候double free,引起崩潰的問題。
因此如果沒有必要,通常會禁用該介面,避免使用者呼叫該介面造成問題。
禁用的方式主要有兩種:
一、C++11 中可以直接使用 =delete
來禁用該介面
class Basic
{
public:
Basic();
// 禁用複製建構函式
Basic(const Basic& bs) = delete;
// 禁用賦值運算子
Basic& operator=(const Basic& bs) = delete;
~Basic();
private:
int num1;
int* p1;
};
此時使用者將無法呼叫該介面,否則會編譯報錯
delete
除了可以應用於類的成員函式,也可以應用於非成員函式
二、將其宣告為私有的成員函式
另一種方式就是將其宣告為私有的成員函式,然後只是宣告,無需進行定義(C++中的函式可以只進行宣告,而無需定義,只要該函式不被呼叫就可以正常編譯,如果被呼叫的話,就會出現連結錯誤)。
class Basic
{
public:
Basic();
~Basic();
private:
Basic(const Basic& bs); // 複製建構函式宣告為私有
Basic& operator=(const Basic& bs); // 賦值運算子宣告為私有
private:
int num1;
int* p1;
};
透過這種方式外部將無法呼叫該介面
參考資料:
Prefer deleted functions to private undefined ones.