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

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

class A
{
public:
    A() = default;

private:
    A(const A&) = delete;
};

Всегда ли эти два определения идентичны друг другу в каких-либо случаях?


person xmllmx    schedule 21.09.2013    source источник
comment
Я делаю свои удаленные функции общедоступными, потому что это объявление для общедоступных пользователей о том, что они не могут быть созданы по умолчанию (в вашем случае).   -  person Nawaz    schedule 21.09.2013


Ответы (2)


Отличаются они только выдаваемой диагностикой. Если вы сделаете это 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.

person Daniel Frey    schedule 21.09.2013
comment
+1. Я делаю свои удаленные функции общедоступными, потому что это объявление для общедоступных пользователей о том, что они не могут быть созданы по умолчанию (в случае OP). - person Nawaz; 21.09.2013
comment
@Nawaz Правильно, поэтому его также можно считать частью интерфейса/документации класса. - person Daniel Frey; 21.09.2013

Я хочу расширить ответ Дэниела Фрея. Вместо того, чтобы делать удаленные методы всегда public, я бы предпочел дать этим методам модификатор доступа, который вы (гипотетически) присвоили бы этим методам, если бы они не удалялись. (Мне не нравится всегда, если у программиста есть выбор. Если бы он действительно был высечен в камне, чтобы сделать удаленные методы public, он должен быть принудительно реализован самим языком.)

Некоторые практические правила/рекомендации:

  • Операторы присваивания копирования и перемещения будут public в конкретных и абстрактных классах в большинстве случаев.
  • Конструкторы копирования и перемещения будут public в конкретных классах в большинстве случаев.
  • Конструкторы копирования и перемещения будут protected в абстрактных классах в большинстве случаев.
  • Конструкторы копирования и перемещения будут private в конкретных final классах, которые могут быть созданы только friends в большинстве случаев.

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

person Matthias    schedule 08.04.2017