#cpp #language_lawyer #деструктор
Следует ли объявлять деструктор производного класса виртуальным, если в базовом классе он уже помечен таковым? Т.е., необходимость в виртуальном деструкторе в базовом классе мне ясна, в производном - нет. Возможно, не задумывался бы об этом, если бы не натыкался на статьи, в которых даны примеры, где по мнению авторов наличие виртуальных деструкторов в производных классах является, видимо, хорошим тоном.
Ответы
Ответ 1
Согласно стандарту C++ (7.1.2 Function specifiers) 5 The virtual specifier shall be used only in the initial declaration of a non-static class member function; То есть спецификатор функции virtual обязан присутствовать только в первоначальном объявлении функции. Тем не менее я соглашусь, что присутствие этого спецификатора в объявлениях функций в производных классах делает код более ясным и самодокументируемым. Что касается деструкторов, то, опять-таки, согласно стандарта C++ (10.3 Virtual functions) 6 Even though destructors are not inherited, a destructor in a derived class overrides a base class destructor declared virtual; see 12.4 and 12.5. То есть если деструктор в базовом классе объявлен со спецификатором virtual, то деструктор в производном классе переопределяет деструктор базового класса, то есть ведет себя как виртуальная функция.Ответ 2
Он автоматически будет виртуальным. Достаточно пометить функцию-член как виртуальную в базовом классе; такой она будет и в производном. #includeusing namespace std; class B { public: virtual void f() const { cout << "B\n"; } virtual ~B() { cout << "~B\n"; } }; class C: public B { public: void f() const { cout << "C\n"; } ~C() { cout << "~C\n"; } }; class D: public C { public: void f() const { cout << "D\n"; } ~D() { cout << "~D\n"; } }; int main() { B*b = new D; b->f(); delete b; } Хотя D::f() не имеет слова virtual, это ничего не меняет... Код тут: http://ideone.com/mqG4NW Ответ 3
Как и все остальные переопределенные виртуальные функции, его надо помечать как override, virtual при этом писать не нужно. struct Derived : Base { ~Derived() override; };
Комментариев нет:
Отправить комментарий