boost :: noncopyable如何工作

时间:2016-08-15 16:40:50

标签: c++ boost

在我的C ++实践中,我偶然发现了两个愚蠢的问题:

  1. c ++拷贝构造函数和赋值运算符中的AFAIK不是继承的......那么在这种情况下boost :: noncopyable如何帮助禁止这些东西?

    class X: private boost::noncopyable
    {
    };
    
    是否有必要使用只有私人继承来实现目标?

  2. 是否只有一种方式来声明赋值运算符

    MyClass& operator= ( const MyClass & );
    
    声明
    void operator= ( const MyClass & ); 
    const MyClass& operator= ( const MyClass & );
    是否相同?

2 个答案:

答案 0 :(得分:2)

C ++ 11及更高版本中的不可复制将通过声明它=delete来工作,最好是公共的。但是,在C ++ 11之前,这是不可能的,并且正在使用2种技术的组合:

  • 声明方法私有
  • 不要实施方法

通过将该方法设为私有,非友元类无法调用此方法。因此,任何试图调用它的代码都会导致编译错误。

在实践中,班级仍然可以复制自己。因此,此方法无法实现,您将收到链接器错误。

继承boost::noncopyable将阻止第二个用例,但是,它也会阻止编译器生成有效的默认复制构造函数......因为它们会违反先前的约束。

请注意,如果您真的想要,可以通过调用这些“不可复制”的正常构造函数来为继承类编写复制构造函数。类。

对于你的第二个问题:是的,你可以给它任何你想要的返回类型,尽管你不能再写a = b = c;了。

答案 1 :(得分:1)

您是正确的,不会继承复制构造函数和复制赋值运算符。幸运的是,我们不需要继承它们才能使其工作。如果继承自无法复制的类,则无法复制该派生类,也无法在其复制构造函数中调用基类复制构造函数。

您必须从类似

的类继承
struct NonCopyable {
    NonCopyable & operator=(const NonCopyable&) = delete;
    NonCopyable(const NonCopyable&) = delete;
    NonCopyable() = default;
};

这足以阻止编译器在派生类中生成的副本和赋值工作。你可以自己提供并覆盖它,但那就是失败了。