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++中没有拷贝构造函数,这个模式实现可能比较困难。

广告

我自己模仿muduo写了一个HTTP服务器,欢迎大家交流指导。

参考


chenBright
817 声望57 粉丝

学习算法、C++、linux…