Должен ли удаленный конструктор быть закрытым?

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 для большинства случаев.

Во всех случаях вы делаете объявление подходящим пользователям класса, а не всем пользователям класса.