C++ noncopyable類

muduo中,有一個noncopyable類,繼承了該類的派生類不能被拷貝,只能被移動。涉及拷貝的函數有兩個:拷貝構造函數和拷貝複製操作符。將這兩個方法聲明爲不可訪問或者刪除(=delete),即可達到不可拷貝的效果。

將函數聲明爲private

將拷貝構造函數和拷貝複製操作符聲明爲 private,能阻止編譯器創建這兩個函數,同時阻止用戶調用它們,從而達到阻止拷貝的效果。實現如下:

class noncopyable {
public:
    ...
private:
    
    noncopyable(const noncopyable&);
    noncopyable& operator=(const noncopyable&);
};

《Effective C++》第三版 條款06介紹的就是這種實現。

使用方法:

class myClass : private noncopyable {};

注意:此處一定要使用private 繼承,以防止 member 函數和 friend 函數訪問。

C++ 11 下使用 delete 關鍵字

C++ 11 下可以使用 delete 關鍵字可以很方便地實現。

class noncopyable {
public:
    
    noncopyable(const noncopyable&) = delete;
    noncopyable& operator=(const noncopyable&) = delete;
};

Boost 中的實現

boot::noncopyable的實現結合了前面兩種方法:

class noncopyable {
protected:
    // 默認的構造函數和析構函數是 protected,
    // 不允許創建 noncopyable 實例,但允許子類創建實例
    // (即允許派生類構造和析構)。
    noncopyable() = default;
    ~noncopyable() = default;

private:
    // 使用 delete 關鍵字禁止編譯器自動產生複製構造函數和複製賦值操作符。
    noncopyable(const noncopyable&) = delete;
    const noncopyable& operator=(const noncopyable&) = delete;
};

阻止拷貝的限制

爲什麼很多人禁用拷貝(複製)構造函數中提到,阻止拷貝有幾點限制:

  • 在C++11之前對象必須有正常的拷貝語義才能放入容器中,禁用拷貝構造的對象無法直接放 入容器中,當然你可以使用指針來規避這一點,但是你又落入了自己管理指針的困境之中 (或許使用智能指針可以緩解這一問題)。
  • C++11中存在移動語義,你可以通過移動而不是拷貝把數據放入容器中。
  • 拷貝構造函數的另一個應用在於設計模式中的原型模式,在C++中沒有拷貝構造函數,這個模式實現可能比較困難。

參考

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章