【问题标题】:Can a non-copyable member be used as alternative to make an object non-copyable?可以使用不可复制的成员作为使对象不可复制的替代方法吗?
【发布时间】:2019-03-05 08:16:55
【问题描述】:

具有不可复制成员的类也被称为不可复制。从 SO,为了使类不可复制,这些选项是:

  1. 使用 boost::noncopyable
  2. 将构造函数和赋值运算符声明为私有。
  3. 删除复制构造函数。

    class foo 
    {
        private:
          std::mutex _dummy;
    };
    

问题:是否将包含一个虚拟的不可复制成员用于类似目的和简单性?缺点是什么?

【问题讨论】:

  • 你标记了这个问题 C++11。有什么原因你不能只 = delete 复制构造函数?
  • @NicolBolas:谢谢我补充。
  • “是否将包含一个虚拟的不可复制成员用于类似目的和简单性?有什么缺点?” - 不,还不够。你可以编写一个不做任何事情的复制构造函数。
  • 总是说出你的意思——添加一个不可复制的对象(特别是像互斥体之类的东西)只会混淆你的代码。只需删除复制构造函数和可能的赋值运算符。
  • @max66 是的,已经够了,只是不可取。

标签: c++ c++11


【解决方案1】:

从 C++11 开始,使类不可复制的正确习惯用法是 = delete 复制构造函数/赋值运算符。这就是 C++ 程序员被告知要做的事情,这也是其他 C++ 程序员在你的类中寻找这种行为时所期望看到的。

拥有一个不可复制的子对象(成员或基类)很好,因此您的默认复制构造函数/赋值运算符将被隐式删除。但是您应该只对 碰巧不可复制的子对象执行此操作。也就是说,您有一个 unique_ptr<T>mutex 或其他任何成员,因为您需要 unique_ptr<T>mutex 作为类实例数据。不是因为您将其用作使该类型不可复制的技巧。

为此目的使用成员子对象的缺点是:

  1. 它混淆了代码的含义。您的mutex _dummy; 示例告诉我您的类型中有一个mutex。如果没有人使用该变量,那么这告诉我您的代码相当不连贯;如果您不需要子对象,则无需声明子对象。 = delete 是正确的习惯用法,所以你应该使用它。

  2. boost::noncopyable 是 C++98/03 的习惯用法,因为它是一个空类。因此,常见的空基优化将确保它不会占用派生类中的任何空间。空成员没有得到这样的优化,所以成员boost::noncopyable 总是会让你的班级更大,没有任何优势。虽然您可以指向即将到来的 C++20 [[no_unique_address]] 属性,但请参阅原因 #1。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-02-16
    • 2012-04-29
    • 1970-01-01
    • 2020-09-14
    • 2014-06-03
    • 2017-03-07
    相关资源
    最近更新 更多