Правило нуля - конструктор по умолчанию не создается

Я читал это: https://en.cppreference.com/w/cpp/language/rule_of_three

Насколько я понимаю, если вы хотите иметь базовый класс с виртуальным деструктором, вам необходимо определить все 5 специальных функций (извлеченных из раздела правила 0):

      class base_of_five_defaults
{
 public:
    base_of_five_defaults(const base_of_five_defaults&) = default;
    base_of_five_defaults(base_of_five_defaults&&) = default;
    base_of_five_defaults& operator=(const base_of_five_defaults&) = default;
    base_of_five_defaults& operator=(base_of_five_defaults&&) = default;
    virtual ~base_of_five_defaults() = default;
};

однако, когда я пытаюсь установить этот класс, я получаю сообщение об ошибке «c'tor по умолчанию не создается»:

          base_of_five_defaults b; // Error

Затем, если я сгенерирую значение по умолчанию, все в порядке:

      base_of_five_defaults() = default;

Но я не понимал, что это вообще нужно ... поэтому я не понимаю, почему его там нет. Я думал, что единственная причина, по которой компилятор не создает конструктор по умолчанию, заключается в том, что вы указываете конструктор, отличный от конструктора по умолчанию ...

Если вам ДЕЙСТВИТЕЛЬНО нужно указать c'tor по умолчанию, тогда класс в примере не может быть сконструирован, что кажется странным.

Вот ссылка на мой полный живой пример: https://godbolt.org/z/qPvjd6r51


Из https://en.cppreference.com/w/cpp/language/default_constructor:

Неявно объявленный конструктор по умолчанию

Если для типа класса (структура, класс или объединение) не предусмотрены никакие объявленные пользователем конструкторы, компилятор всегда будет объявлять конструктор по умолчанию как встроенный публичный член своего класса.

Я думаю, это означает, что если объявлен, тогда он считается объявленным пользователем, даже если его "по умолчанию"?

1 ответ

Решение

Я думаю, это означает, что если base_of_five_defaults(const base_of_five_defaults&) = default; объявлен, тогда он считается объявленным пользователем, даже если его "по умолчанию"?

Да . base_of_five_defaults(base_of_five_defaults&&) = default;объявляет с 1 дефолтом пользователя объявлено конструктором.

В = default заставляет компилятор генерировать определение такого конструктора, но он был объявлен пользователем.

Стандарт C ++ не предоставляет явного определения « объявлено пользователем», поэтому английский язык вступает в игру, чтобы означать, ну, «объявлено пользователем».

Вот где вас кусает:

Конструктор по умолчанию для класса X - это конструктор класса X, для которого каждый параметр, не являющийся пакетом параметров функции, имеет аргумент по умолчанию (включая случай конструктора без параметров).
Если для класса X не существует объявленного пользователем конструктора, неявный конструктор, не имеющий параметров, неявно объявляется как заданный по умолчанию ([dcl.fct.def]).
Неявно объявленный конструктор по умолчанию является встроенным публичным членом своего класса.


1) Неважно, конструктор это с параметрами или без, см. Формулировку [class.default.ctor]/1.

Другие вопросы по тегам