Деструктор производного класса

201
26 апреля 2017, 12:32

Следует ли объявлять деструктор производного класса виртуальным, если в базовом классе он уже помечен таковым? Т.е., необходимость в виртуальном деструкторе в базовом классе мне ясна, в производном - нет. Возможно, не задумывался бы об этом, если бы не натыкался на статьи, в которых даны примеры, где по мнению авторов наличие виртуальных деструкторов в производных классах является, видимо, хорошим тоном.

Answer 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, то деструктор в производном классе переопределяет деструктор базового класса, то есть ведет себя как виртуальная функция.

Answer 2

Он автоматически будет виртуальным.

Достаточно пометить функцию-член как виртуальную в базовом классе; такой она будет и в производном.

#include <iostream>
using 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

Answer 3

Как и все остальные переопределенные виртуальные функции, его надо помечать как override, virtual при этом писать не нужно.

struct Derived : Base {
  ~Derived() override;
};
READ ALSO
операции с числами в разных системах счисления C++ builder [требует правки]

операции с числами в разных системах счисления C++ builder [требует правки]

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

284
Как записать двуменый массив в вектор? С++

Как записать двуменый массив в вектор? С++

Выдаёт ошибку: vector subscript out of rangeНикак не могу найти ошибку

219
Ошибка в строке с break (Uncaught SyntaxError: Illegal break statement)

Ошибка в строке с break (Uncaught SyntaxError: Illegal break statement)

оператор break может использовать только внутри цикла

415
Событие на scroll

Событие на scroll

Как сделать событие, которое запускается когда scroll достигает самого верха в блоке?

252