The C++ Standard, [expr.delete], paragraph 3 [ISO/IEC 14882-2014], states the following:
In the first alternative (delete object), if the static type of the object to be deleted is different from its dynamic type, the static type shall be a base class of the dynamic type of the object to be deleted and the static type shall have a virtual destructor or the behavior is undefined. In the second alternative (delete array) if the dynamic type of the object to be deleted differs from its static type, the behavior is undefined.
Do not delete an object of derived class type through a pointer to its base class type that has a non-
virtual destructor. Instead, the base class should be defined with a
virtual destructor. Deleting an object through a pointer to a type without a
virtual destructor results in undefined behavior.
Noncompliant Code Example
In this noncompliant example,
b is a polymorphic pointer type whose static type is
Base * and whose dynamic type is
Derived *. When
b is deleted, it results in undefined behavior because
Base does not have a
virtual destructor. The C++ Standard, [class.dtor], paragraph 4 [ISO/IEC 14882-2014], states the following:
If a class has no user-declared destructor, a destructor is implicitly declared as defaulted. An implicitly declared destructor is an
inline publicmember of its class.
The implicitly declared destructor is not declared as
virtual even in the presence of other
Noncompliant Code Example
In this noncompliant example, the explicit pointer operations have been replaced with a smart pointer object, demonstrating that smart pointers suffer from the same problem as other pointers. Because the default deleter for
delete on the internal pointer value, the resulting behavior is identical to the previous noncompliant example.
In this compliant solution, the destructor for
Base has an explicitly declared
virtual destructor, ensuring that the polymorphic delete operation results in well-defined behavior.
OOP52-CPP:EX0: Deleting a polymorphic object without a virtual destructor is permitted if the object is referenced by a pointer to its class, rather than via a pointer to a class it inherits from.
Note that if
Derived were not marked as
delete this could actually reference a subclass of
Derived, violating this rule.
OOP52-CPP:EX1: Deleting a polymorphic object without a virtual destructor is permitted if its base class has a destroying
operator delete that will figure out the correct derived class's destructor to call by other means.
Attempting to destruct a polymorphic object that does not have a
virtual destructor declared results in undefined behavior. In practice, potential consequences include abnormal program termination and memory leaks.
|Axivion Bauhaus Suite|
delete with Non-Virtual Destructor
C++3402, C++3403, C++3404
|LDRA tool suite|
Define a virtual destructor in classes used as base classes which have virtual functions
3402, 3403, 3404
|Polyspace Bug Finder|
|CERT C++: OOP52-CPP||Checks for situations when a class has virtual functions but not a virtual destructor (rule partially covered)|
|SonarQube C/C++ Plugin|
|SEI CERT C++ Coding Standard|
Subclause 5.3.5, "Delete"
|[Stroustrup 2006]||"Why Are Destructors Not Virtual by Default?"|