是否足以删除operator =(Type type)?

时间:2013-07-04 21:40:34

标签: c++ c++11

对于不可移动的类型,是否足够(从最佳实践角度来看)?

class A
{
   A(const A&) = delete;
   A(A&&) = delete;
   A& operator=(A) = delete;
public:
   A();
};

或者我是否必须单独删除复制/移动赋值运算符?这里还需要一个析构函数吗?

2 个答案:

答案 0 :(得分:8)

是的,将复制构造函数和复制赋值运算符声明为deleted就足够了。由于您要声明复制构造函数和复制赋值运算符,因此不会自动生成移动构造函数和移动赋值运算符。您无需明确声明它们deleted

来自§12.8/ 9(强调增加)

  

如果类X的定义没有明确声明一个移动构造函数,那么当且仅当时,才会隐式声明一个默认     - X没有用户声明的拷贝构造函数,
    - X没有用户声明的复制赋值运算符,
    - X没有用户声明的移动赋值运算符,
    - X没有用户声明的析构函数,以及
    - 移动构造函数不会被隐式定义为已删除。

来自§12.8/ 20(强调增加)

  

如果类X的定义没有明确声明一个移动赋值运算符,那么当且仅当时,才会将其隐式声明为默认值    - X没有用户声明的拷贝构造函数,
   - X没有用户声明的移动构造函数,
   - X没有用户声明的复制赋值运算符,
   - X没有用户声明的析构函数,以及
   - 移动赋值运算符不会被隐式定义为已删除。

答案 1 :(得分:3)

根据[class.copy] / 17 operator=(A)是一个有效的复制赋值运算符,所以是的,声明删除它就足以抑制隐式移动赋值运算符,因此与删除的复制构造函数一起将使类不可复制和不可移动。

你的班级比必要的复杂,但你需要的只是:

class A
{
   A(const A&) = delete;
   A& operator=(A) = delete;
public:
   A();
};

用户声明的复制构造函数禁止隐式移动构造函数,用户声明的复制赋值运算符禁止隐式移动赋值运算符。

但是,operator=(A)形式是非惯用的,所以无论如何我都倾向于使用operator=(const A&) = delete。它具有相同的效果。

N.B。没有理由将已删除的函数声明为私有,实际上它会导致更糟糕的诊断。根据我的经验,公开和删除效果更好。

  

这里还需要一个析构函数吗?

需要什么?这取决于你的默认构造函数。