Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When should you not use virtual destructors?

Is there ever a good reason to not declare a virtual destructor for a class? When should you specifically avoid writing one?

like image 634
Mag Roader Avatar asked Nov 19 '08 04:11

Mag Roader


People also ask

When should you use virtual destructors C++?

Virtual keyword for destructor is necessary when you want different destructors should follow proper order while objects is being deleted through base class pointer.

What is a virtual destructor and in what situation should it be used?

A virtual destructor is used to free up the memory space allocated by the derived class object or instance while deleting instances of the derived class using a base class pointer object.

Why do you need virtual destructor?

CPP. Making base class destructor virtual guarantees that the object of derived class is destructed properly, i.e., both base class and derived class destructors are called. For example, CPP.

What is non virtual destructor in C++?

A C++ class containing virtual member functions has a non-virtual destructor. Since this class has virtual member functions, it will be used as a base class. The use of non-virtual destructors in base classes is dangerous because it can cause objects to be torn down incorrectly.


3 Answers

There is no need to use a virtual destructor when any of the below is true:

  • No intention to derive classes from it
  • No instantiation on the heap
  • No intention to store with access via a pointer to a superclass

No specific reason to avoid it unless you are really so pressed for memory.

like image 154
sep Avatar answered Oct 20 '22 19:10

sep


To answer the question explicitly, i.e. when should you not declare a virtual destructor.

C++ '98/'03

Adding a virtual destructor might change your class from being POD (plain old data)* or aggregate to non-POD. This can stop your project from compiling if your class type is aggregate initialized somewhere.

struct A {
  // virtual ~A ();
  int i;
  int j;
};
void foo () { 
  A a = { 0, 1 };  // Will fail if virtual dtor declared
}

In an extreme case, such a change can also cause undefined behaviour where the class is being used in a way that requires a POD, e.g. passing it via an ellipsis parameter, or using it with memcpy.

void bar (...);
void foo (A & a) { 
  bar (a);  // Undefined behavior if virtual dtor declared
}

[* A POD type is a type that has specific guarantees about its memory layout. The standard really only says that if you were to copy from an object with POD type into an array of chars (or unsigned chars) and back again, then the result will be the same as the original object.]

Modern C++

In recent versions of C++, the concept of POD was split between the class layout and its construction, copying and destruction.

For the ellipsis case, it is no longer undefined behavior it is now conditionally-supported with implementation-defined semantics (N3937 - ~C++ '14 - 5.2.2/7):

...Passing a potentially-evaluated argument of class type (Clause 9) having a non-trivial copy constructor, a non-trivial move constructor, or a on-trivial destructor, with no corresponding parameter, is conditionally-supported with implementation-defined semantics.

Declaring a destructor other than =default will mean it's not trivial (12.4/5)

... A destructor is trivial if it is not user-provided ...

Other changes to Modern C++ reduce the impact of the aggregate initialization problem as a constructor can be added:

struct A {
  A(int i, int j);
  virtual ~A ();
  int i;

  int j;
};
void foo () { 
  A a = { 0, 1 };  // OK
}
like image 21
Richard Corden Avatar answered Oct 20 '22 20:10

Richard Corden


I declare a virtual destructor if and only if I have virtual methods. Once I have virtual methods, I don't trust myself to avoid instantiating it on the heap or storing a pointer to the base class. Both of these are extremely common operations and will often leak resources silently if the destructor is not declared virtual.

like image 29
Andy Avatar answered Oct 20 '22 18:10

Andy