【问题标题】:Deleting copy constructors and copy assignment operators. Which of them are essential?删除复制构造函数和复制赋值运算符。其中哪些是必不可少的?
【发布时间】:2016-02-19 23:46:03
【问题描述】:

我有一个用例,我的对象不能以任何方式复制。我在下面写了一个夸大的复制构造函数和复制赋值运算符删除的完整列表。它们太多了,我无法确定要使用哪些,有时这让我很偏执。我不必将它们全部写在我的代码中,是吗?那么,为了防止任何形式的对象复制,我应该使用哪一个?

        MyClass             (       MyClass &)  = delete;
        MyClass             (const  MyClass &)  = delete;
        MyClass             (       MyClass &&) = delete;
        MyClass             (const  MyClass &&) = delete;
        MyClass    operator=(       MyClass &)  = delete;
        MyClass    operator=(const  MyClass &)  = delete;
const   MyClass    operator=(       MyClass &)  = delete;
const   MyClass    operator=(const  MyClass &)  = delete;
        MyClass &  operator=(       MyClass &)  = delete;
        MyClass &  operator=(const  MyClass &)  = delete;
const   MyClass &  operator=(       MyClass &)  = delete;
const   MyClass &  operator=(const  MyClass &)  = delete;
        MyClass && operator=(       MyClass &)  = delete;
        MyClass && operator=(const  MyClass &)  = delete;
const   MyClass && operator=(       MyClass &)  = delete;
const   MyClass && operator=(const  MyClass &)  = delete;
        MyClass    operator=(       MyClass &&) = delete;
        MyClass    operator=(const  MyClass &&) = delete;
const   MyClass    operator=(       MyClass &&) = delete;
const   MyClass    operator=(const  MyClass &&) = delete;
        MyClass &  operator=(       MyClass &&) = delete;
        MyClass &  operator=(const  MyClass &&) = delete;
const   MyClass &  operator=(       MyClass &&) = delete;
const   MyClass &  operator=(const  MyClass &&) = delete;
        MyClass && operator=(       MyClass &&) = delete;
        MyClass && operator=(const  MyClass &&) = delete;
const   MyClass && operator=(       MyClass &&) = delete;
const   MyClass && operator=(const  MyClass &&) = delete;

【问题讨论】:

  • 这确实有点偏执:)
  • 它也不会编译,因为你不能重载返回值。
  • 另外,你忘了volatile ;-)

标签: c++ copy-constructor copy-assignment deleted-functions implicit-methods


【解决方案1】:

您只需将单个复制构造函数和复制赋值运算符标记为delete。复制版本的存在将阻止移动构造函数和移动赋值运算符的隐式声明,并且声明一种形式的复制特殊成员函数会抑制其他形式的隐式声明。

MyClass (const MyClass&) = delete;
MyClass& operator= (const MyClass&) = delete;

请注意,在 C++11 之后,不推荐将赋值运算符隐式定义为默认值,而应将其定义为已删除。

【讨论】:

  • 只是一个非常轻微的挑剔,我可能错了。 definition 不是被弃用的,而不是 declaration 吗?它们总是被声明,但它们的定义被删除。但我不是一个很好的语言律师。
  • @luk32 啊,你是对的,它应该被隐式声明并定义为删除,([class.copy]/18),谢谢。
【解决方案2】:

copy constructor

MyClass             (const  MyClass &)  = delete;

assignement operator

MyClass &  operator=(const  MyClass &)  = delete;

这些是唯一隐式定义的复制构造函数和复制赋值运算符。

【讨论】:

  • operator= 不是构造函数;并且通常可以隐式定义其他构造函数 - 但用户定义的MyClass (const MyClass &) 的存在会抑制其他构造函数。
  • 您的“解决方案”很好,但答案实际上是错误的。正确的推理是所有赋值运算符和构造函数都是隐式定义的,除非除其他原因外,您手动定义一个。为此目的,删除算作定义。
猜你喜欢
  • 2020-04-18
  • 2011-07-19
  • 1970-01-01
  • 1970-01-01
  • 2013-04-13
  • 1970-01-01
  • 2014-05-18
  • 1970-01-01
相关资源
最近更新 更多