在C++11中,如果想要禁止类的拷贝行为只需要把相应的函数设为delete
即可,参见标准库的std::unique_ptr
unique_ptr (const unique_ptr&) = delete;
unique_ptr& operator= (const unique_ptr&) = delete;
而在之前的标准中是把相应的函数作为private
函数。
然而,对于普通的类,如果不去查看类的成员函数声明,我们是无法知道该类是否为不可复制的类型。在C++中,利用继承的技巧可以简单实现noncopyable
类。
class NonCopyable {
protected:
NonCopyable(const NonCopyable&) = delete;
NonCopyable& operator=(const NonCopyable&) = delete;
NonCopyable() = default;
~NonCopyable() = default;
};
只需要继承该类就可以保证派生类不可复制
class A : public NonCopyable {};
int main() {
A a1;
A a2 = a1; // 编译错误
A a3;
a3 = a1; // 编译错误
return 0;
}
这里利用到的是C++的合成构造函数,当派生类调用默认的构造函数/析构函数/拷贝构造函数/赋值运算符时,会先调用基类默认的构造函数/析构函数/拷贝构造函数/赋值运算符,而基类中拷贝构造函数和赋值运算符均不可用,所以派生类无法进行拷贝行为。同时,给NonCopyable类声明默认构造函数/析构函数,使得在派生类中能够调用基类(NonCopyable)的相应函数来构造/析构基类部分。
当然,如果需要的话,派生类也可以定义拷贝构造函数和赋值运算符,这种行为是允许的,但逻辑上产生了矛盾,属于程序员的失误。
class A : private NonCopyable {
public:
A(int i) : i_(i) {}
A(const A& rhs) : i_(rhs.i_) {}
A& operator=(const A& rhs) { i_ = rhs.i_; return *this; }
void show() { cout << i_ << endl;}
private:
int i_;
};
int main() {
A a1(3);
A a2 = a1; // OK
a2 = a1; // OK
a2.show();
return 0;
}
参考boost::noncopyable的实现