C++实现用来继承的noncopyable类

在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的实现

你可能感兴趣的:(C++实现用来继承的noncopyable类)