Как правильно реализовать деструктор класса C ++ - PullRequest
3 голосов
/ 16 октября 2019

В классе (без членов прямого указателя), я вижу, есть следующие 3 возможности для определения деструктора.

class Child : public Parent
{
public:
    // ~Child() override {}          // (1) explicit destructor with empty body
    // ~Child() override = default;  // (2) explicit default destructor
    //                               // (3) implicit default destructor


private:
    // members
}

Можно ли / нужно всегда избегать опции (1)? Потому что Clang-Tidy намекает мне выбрать опцию (2), если я использую опцию (1).

Каковы различия между тремя различными опциями в целом? Что следует учитывать при выборе одного из других?

Ответы [ 3 ]

5 голосов
/ 16 октября 2019

Можно ли / нужно всегда избегать опцию (1)?

Предполагая не древнюю версию языка, да. Насколько я могу судить, единственная причина для использования пустого деструктора не по умолчанию - это поддержка C ++ 03 и более старых стандартов.

Что следует учитывать при выборе одного из других?

    1. и 3. Преимущество в том, что он действителен во всех версиях C ++ (без указания спецификатора override).
  • и 3. Преимущество состоит в том, что они тривиальны, пока элементы тривиально разрушаемы.
    1. и 2. имеют преимущество, позволяющее деструктору бытьопределяется отдельно от определения класса (которое не было использовано в примере). Это важно, например, если у вас есть уникальный указатель на неполный тип в качестве члена. Это типично при реализации шаблона PIMPL.
    1. и 2. также имеют то преимущество, что деструктор может быть явно объявлен виртуальным, что обычно необходимо для полиморфной базыклассы.
    1. Недостатком является то, что использование неявно объявленного конструктора копирования и оператора присваивания исключено. Это означает, что на него не следует полагаться, и он может в будущем перестать работать. Как 1., так и 2. имеют недостаток, заключающийся в предотвращении генерации неявного конструктора перемещения и оператора присваивания. Поэтому, если вы используете любой из них, вам также следует объявить конструкторы копирования и перемещения и операторы присваивания (по умолчанию, если это возможно).
  • Преимуществом является наименьшее количество для записи и наименьшее количество для чтения, особенно с учетом предыдущего абзаца.

В качестве грубого практического правила используйте 3., есливозможно. Если это невозможно (например, в случае PIMPL, описанном выше), используйте 2. Если это невозможно (т. Е. Необходимо поддерживать C ++ 03), используйте 1.

3 голосов
/ 16 октября 2019

C ++ использует RAII принцип. Тесно связано Правило трех / пяти / нуля .

Это выглядит так:

  • если ваш класс является владельцем ресурса, тоон должен реализовывать все 3/5 специальных членов (конструктор копирования / перемещения, назначение копирования / перемещения и деструктор), чтобы соблюдать принцип RAII
  • в соответствии, если вам необходимо определить хотя бы один из 3/5специальные члены, тогда ваш класс, скорее всего, владеет ресурсом, поэтому вы должны определить все 3/5
  • , если ваш класс владеет ресурсом, то он должен иметь дело исключительно с резервированием этого ресурса. Иначе он не должен определять ни одного из упомянутых специальных членов (Правило нуля).

Вы определенно находитесь на территории "Правило нуля", как и весь ваш код. Так что вам нужен неявный деструктор.

3 голосов
/ 16 октября 2019

Можно ли / всегда избегать option (1)?

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

Каковы различия между тремя различными вариантами в целом?

Предполагая, что в вашем деструкторе не должно быть ничего особенного:

  1. Вы блокируете деструктор пустым, если что-то изменится, вы можете забыть добавить его в свой деструктор.

  2. Пусть компилятор разберется со всем этими покажите в коде, что вы делаете это.

  3. Дайте компилятору понять все это и не покажите в коде, что вы делаете это.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...