невиртуальные деструкторы в c с переопределением

#c #virtual #destructor

#c #виртуальные #деструктор

Вопрос:

Да, я видел много сообщений об использовании ключевых слов virtual и override для деструкторов в C . Я также думаю, что понимаю использование:

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

Однако мне интересно — или я видел это также несколько раз в чьем-то коде, что он используется так:

 class Base
{
   public:
          ~Base();
};

class Derived : public Base
{
   public:
         ~Derived() override;
};
 

Действительно ли это переопределение деструктора невиртуальной функции в базовом классе оказывает какое-либо влияние на программу / компиляцию или что-то еще? Или в этом случае он просто используется неправильно?

Комментарии:

1. Это не будет компилироваться.

2. GCC: error: 'Derived::~Derived()' marked 'override', but does not override

3. Ваш код не компилируется

4. Что не будет компилироваться? И почему, потому что из-за «переопределения»?

5. @malajedala да, вам не нужно повторять ключевое слово «virtual» в производных классах, хотя я бы рекомендовал это делать (чтобы избежать именно той путаницы, которая у вас только что была).

Ответ №1:

Ваш код не компилируется, потому Base::~Base что не является виртуальным.

О, хорошо, может быть, я заметил это: если базовый класс является производным от другого класса, скажем, класса SuperBase, который имеет виртуальный деструктор, тогда деструктор Base будет виртуальным без использования ключевого слова right ?

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

Хорошей практикой является всегда использовать ключевое override слово в методе, предназначенном для переопределения. Это имеет два больших преимущества: это дает понять читателю-человеку, что метод является виртуальным и переопределяет, и позволяет избежать некоторых ошибок, когда метод имеет отступ для переопределения, но он молча этого не делает (например const , несоответствие).

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

Комментарии:

1. Хотя все это правильно, вы могли бы добавить комментарий о «специальном случае деструктора», поскольку они могут быть переопределены (и виртуальны), несмотря на наличие «разных имен».