C++ 禁用類的複製建構函式和賦值運算子

Jeffxue發表於2024-08-09

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.

相關文章