Should the destructor always be virtual if the class is part of a larger structure?

There is this question on stackoverflow that defends Scott Meyers' rule only for creating a virtual destructor if there are virtual functions in that class.

I work for a company with a large structure and it is not yet clear if your class will be extended in the future. It may also not be possible to modify this class at this point (since it is part of a released package).

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 now it cannot be changed. Now class C

created and used as B

:

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

      

What happens since C's destructor is never called, right?

In this scenario : Should the class always have a virtual destructor ?

+3


source to share


3 answers


As @Konrad Grochowski said in answers, the destructor B

is implicitly virtual, so the behavior is well defined. Your example will be called C::~C()

. From the C ++ specification § 12.4.8:

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

A more local question is what happens when the framework's base class actually has a non-virtual destructor (which I think you are traveling on) and your user gets from it. For example:



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

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

      

As discussed in this question ( Not a virtual destructor in a base class, but a virtual destructor in a derived class causes a segmentation fault ), this can cause your users to run into problems.If you don't know if the user will infer from your class, it must have a virtual destructor, otherwise there are problems.

To ensure correct behavior with non-virtual destructors, you can prevent the user from getting from the class, in which case the non-virtual destructor can be safe if you use the class correctly in your structure. In C ++ 11, you can use final

to disallow output. In C ++ 03 and below, you can use the trick here to disallow the output.

+3


source


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



If a class is to be extended / inherited, it must have a virtual destructor.

+9


source


Scott Meyers, in his book Effective C ++: 55 Concrete Ways to Improve Your Programs and Designs (3rd Edition), says that a destructor must be declared virtual

if a class has a different virtual function. Otherwise, only for virtual destructor

a v-table will be created, which will cause some additional 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.

      

0


source







All Articles