3

There is this question on stackoverflow which advocates Scott Meyers rule of only making a destructor virtual if there are virtual functions in that class.

I am working in a company with a large framework and it is unclear at coding time if your class might be extended in the future. At that point in time it might also be impossible to change that class (because it is part of a released bundle).

Now imagine the following scenario:

class A {
public:
  A();
  virtual ~A();
  virtual m();
};

class B : public A {
public:
  B();
  ~B();
};

class C : public B {
public:
  C();
  virtual ~C();
  virtual m();
};

So I created class B and by now, it cannot be changed. Now class C is created, and is used as a B:

B * b = new C();
delete b;

What will happen is that the destructor of C is never called, right?

Within this scenario: Should a class always have a virtual destructor?

Community
  • 1
  • 1
Pascal
  • 2,197
  • 3
  • 24
  • 34
  • The real answer is to not abuse inheritance to extend classes. Use composition instead. – nwp May 22 '15 at 11:16
  • With legacy code, using inheritance is often the only way to fix bugs or behavior. For example, my code will get reused without the possibility to change it. – Pascal May 28 '15 at 09:30

3 Answers3

9

when base class have virtual destructor, all classes inheriting from it automatically have virtual destructor (so in your example - B's destructor is implicit virtual)

if class is intended to be extended/inherited it should have virtual destructor.

Hcorg
  • 11,598
  • 3
  • 31
  • 36
3

As @Konrad Grochowski's answer states, the destructor of B is implictly virtual, so the behavior is well defined. In your example, C::~C() will be called. From the C++ spec § 12.4.8:

A destructor can be declared virtual (10.3) or pure virtual (10.4); if any objects of that class or any derived class are created in the program, the destructor shall be defined. If a class has a base class with a virtual destructor, its destructor (whether user- or implicitly-declared) is virtual.

The more pertinent question, is what happens when your framework base class actually has a non-virtual destructor (which I think is what you were driving at), and your user derives from it. For example:

// Your framework:
class A
{
public:
   A();
   ~A(); // non-virtual
};

// User's class:
class B : public A
{
   B();
   virtual ~B(); // virtual
   virtual void UserMethod();
};

As discussed in this question (Non virtual destructor in base class, but virtual destructor in derived class cause segmentation fault), this could cause your users to run into problems. If you unsure whether the user will derive from your class, it should have a virtual destructor, otherwise there is a potential for problems.

To enforce proper behavior with non-virtual destructors, you could disallow the user from deriving from the class, in which case a non-virtual destructor could be safe, assuming you use the class properly within your framework. In C++11, you can use final to disallow derivation. In C++03 and below, you can use the trick here to disallow derivation.

Community
  • 1
  • 1
MuertoExcobito
  • 9,741
  • 2
  • 37
  • 78
  • We had many occasions where there were bugs (or unwanted behavior) in the code that could not be changed. Sometimes we get around such bugs on a higher level by deriving from them. In such a scenario it is quite bad if the destructor is not virtual. Of course the authors of that code had the best intentions, but could not foresee the environment their code would be run in. – Pascal May 22 '15 at 15:00
  • 1
    In C++11 you do not need tricks to disallow derivation, it can be expressed as `final class A{...};`. – nwp May 28 '15 at 12:48
0

Scott Meyers in his book "Effective C++: 55 Specific Ways to Improve Your Programs and Designs (3rd Edition)" says that a destructor should be declared virtual if the class has another virtual function. Otherwise for only virtual destructor v-table will be created, which will cause to some extra resource consumption.

✦Polymorphic  base  classes  should  declare  virtual  destructors.  If  a
class has any virtual functions, it should have a virtual destructor.
✦Classes not designed to be base classes or not designed to be used
polymorphically should not declare virtual destructors.
nabroyan
  • 3,225
  • 6
  • 37
  • 56