Когда сделать деструктор по умолчанию, используя = default? - PullRequest
5 голосов
/ 28 июня 2019

Хотя использование = default для конструкторов для меня очевидно (т.е. заставлять компилятор создавать конструктор по умолчанию, пока существуют другие ctors), я все еще не могу понять разницу между этими двумя типами деструкторов:

  1. Те, которые используют = default
  2. Те, которые не определены явно и генерируются компилятором автоматически.

Единственное, что мне приходит в голову, это то, что деструкторы группы 1 можно определить как виртуальные, но группа 2 всегда не виртуальна.Итак, это единственная разница между ними?Существуют ли сценарии, когда компилятор не генерирует деструктор, но использование = default заставляет компилятор его сгенерировать?

ps Я проверил множество Qs в stackoverflow, но ни один из них не отвечает на мой Q. Вотнекоторые актуальные вопросы.

  1. Разница между = по умолчанию и {} ctos / деструкторами
  2. По умолчанию виртуальные деструкторы
  3. Разницамежду = по умолчанию и пустым dtrs

1 Ответ

2 голосов
/ 28 июня 2019

(Некоторые из пунктов ниже уже упоминались в комментариях или в связанных вопросах; этот ответ служит для их организации и взаимосвязи.)

Есть, конечно, три способа получить «простой деструктор»:

struct Implicit {};
struct Empty {~Empty() {}};
struct Defaulted {~Defaulted()=default;};

Как конструктор по умолчанию (а не копирование или перемещение), {} и =default; означают в значительной степени то же самое для деструкторов.Интересными свойствами Defaulted являются те (комбинации), которые отличаются от обоих от других.

По сравнению с Empty главное отличие простое: явно дефолтный деструктор может быть тривиальна .Это применимо только в том случае, если значение по умолчанию внутри класса, поэтому нет разницы между {} и =default; в определении вне строки.Точно так же, будучи виртуальным, удаляет любое различие, как и наличие любого члена или базового класса с нетривиальным деструктором.Существует также отличие в том, что деструктор с явным дефолтом может быть неявно определен как удален .Оба эти свойства совместно используются с неявно объявленными деструкторами, поэтому мы должны найти и их отличие.

По сравнению с Implicit, явно дефолтный деструктор подавляет операции перемещения, может быть объявлено private, protected или noexcept(false), а в C ++ 20 могут быть ограничены (но не consteval).Очень незначительно, это может быть объявлено constexpr, чтобы проверить, что это будет так или иначе.Объявление этого inline ничего не делает.(Он также может быть как внешним, так и виртуальным, но, как указано выше, это не может быть причиной для его использования.)

Таким образом, ответ «когда вам нужен тривиальный (или потенциально удаленный) деструктор, которыйимеет другие специальные свойства »- наиболее полезно, контроль доступа или noexcept статус.

...