Должен ли удаленный конструктор быть закрытым?
class A
{
public:
A() = default;
A(const A&) = delete;
};
class A
{
public:
A() = default;
private:
A(const A&) = delete;
};
Являются ли эти два определения всегда одинаковыми друг с другом в любом случае?
Ответы
Ответ 1
Они отличаются только от произведенной диагностики. Если вы сделаете это private
, сообщается о дополнительном и избыточном доступе:
class A
{
public:
A() = default;
private:
A(const A&) = delete;
};
int main()
{
A a;
A a2=a;
}
выводит следующий дополнительный вывод из GCC 4.8:
main.cpp: In function 'int main()':
main.cpp:6:5: error: 'A::A(const A&)' is private
A(const A&) = delete;
^
main.cpp:12:10: error: within this context
A a2=a;
^
поэтому моя рекомендация всегда делать удаленные методы public
.
Ответ 2
Я хочу продлить ответ Даниэля Фрея. Вместо того, чтобы делать удаленные методы всегда public
, я бы предпочел дать этим методам модификатор доступа, который вы предположили бы (гипотетически), чтобы эти методы не удалялись. (Мне не нравится всегда, если у программиста есть опция. Если бы он действительно был высечен на камне, чтобы сделать удаленные методы public
, он должен быть принудительно применен самим языком.)
Некоторые эмпирические правила/рекомендации:
- Скопировать и переместить операторы присваивания в большинстве случаев будут
public
в конкретных и абстрактных классах.
- Скопировать и переместить конструкторы будут
public
в конкретных классах для большинства случаев.
- Копирование и перемещение конструкторов в большинстве случаев будут
protected
в абстрактных классах.
- Копировать и перемещать конструкторы будут
private
в конкретных классах final
, которые могут быть созданы только friends
для большинства случаев.
Во всех случаях вы делаете объявление подходящим пользователям класса, а не всем пользователям класса.