Достаточно ли удалить оператор = (Тип типа)?
Достаточно ли достаточно (с точки зрения лучшей практики) для неподвижного типа?
class A
{
A(const A&) = delete;
A(A&&) = delete;
A& operator=(A) = delete;
public:
A();
};
Или мне нужно удалить операторы присваивания копирования/перемещения отдельно? Также нужен деструктор?
Ответы
Ответ 1
Да, объявление операторов копирования и операторов присваивания копий как deleted
достаточно. Поскольку вы объявляете конструктор копирования и оператор присваивания копии, конструктор перемещения и оператор назначения перемещения не будут автоматически сгенерированы. Вам не нужно явно объявлять их deleted
.
Из § 12.8/9 (добавлен акцент)
Если определение класса X явно не объявляет конструктор перемещения, он будет неявным образом объявлен как дефолт тогда и только тогда, когда
- X не имеет объявленного пользователем конструктора копирования,
- X не имеет объявленного пользователем оператора копирования копий,
- X не имеет объявленного пользователем оператора назначения перемещения,
- X не имеет объявленного пользователем деструктора и
- конструктор перемещения не будет неявно определен как удаленный.
Из §12.8/20 (добавлен акцент)
Если определение класса X явно не объявляет оператор присваивания перемещения, он будет неявным образом объявлен как дефолт тогда и только тогда, когда
- X не имеет объявленного пользователем конструктора копирования,
- X не имеет объявленного конструктора перемещения,
- X не имеет объявленного пользователем оператора копирования копий,
- X не имеет объявленного пользователем деструктора и
- оператор присваивания перемещения не будет неявно определен как удаленный.
Ответ 2
В соответствии с [class.copy]/17 operator=(A)
является допустимым оператором присваивания копии, поэтому да, объявив его удаленным, достаточно, чтобы подавить неявный оператор присваивания перемещения и, следовательно, вместе с удаленным конструктором копии сделает класс non -копируемый и не подвижный.
Ваш класс более сложный, чем необходимо, но все, что вам нужно, это:
class A
{
A(const A&) = delete;
A& operator=(A) = delete;
public:
A();
};
Разработанный пользователем конструктор копирования подавляет неявный конструктор перемещения, и пользовательский оператор присваивания копии подавляет неявный оператор присваивания перемещения.
Однако форма operator=(A)
неидиоматична, поэтому я все равно буду использовать operator=(const A&) = delete
. Он имеет тот же эффект.
N.B. нет причин объявлять удаленные функции частными, и на самом деле это приводит к гораздо худшей диагностике. Публичные и удаленные работы лучше по моему опыту.
Также нужен деструктор?
Требуется для чего? Это зависит от вашего конструктора по умолчанию.