V599. The virtual destructor is not present, although the 'Foo' class contains virtual functions.
The analyzer has found a potential error: a virtual destructor is absent in a polymorphic class.
The following conditions must hold for the analyzer to generate the V599 warning:
- A class object is destroyed by the
operator delete
. - The class has at least one virtual function.
The presence of virtual functions indicates that the class may be used polymorphically. In this case, a virtual destructor is necessary to ensure the object is properly destroyed.
Look at the following code sample:
class Father
{
public:
Father() { .... }
~Father() { .... }
virtual void Foo() { .... }
};
class Son : public Father
{
public:
int *buffer;
Son() : Father() { buffer = new int[1024]; }
~Son() { delete[] buffer; }
virtual void Foo() { .... }
};
....
Father *object = new Son();
delete object; // Calls object->~Father(),
// not object->~Son()!!
The code is incorrect and leads to a memory leak. When the object is deleted, only the destructor in the Father
class is called. To call the Son
class' destructor, make the destructor virtual.
This is the correct code:
class Father
{
public:
Father() { .... }
virtual ~Father() { .... }
virtual void Foo() { .... }
};
The V599 diagnostic rule does not catch every issue related to missing virtual destructors. Imagine the following: you develop a library, it contains the XXX class which has virtual functions but no virtual destructor. Since you don't use this class internally within the library, the analyzer won't warn you about the danger. However, problems may arise for developers using your library if their classes inherit from the XXX class.
Compiler warnings, such as C4265
in MSVC and Wdelete-non-virtual-dtor
in GCC/Clang, can detect more issues. These warnings are useful but disabled by default, likely because they often produce false positives in code that uses the mixin pattern. This pattern involves numerous interface classes which contain virtual functions but don't require a virtual destructor.
We can say that the V599 diagnostic rule is a special case of C4265. It produces fewer false reports but, unfortunately, allows you to detect fewer defects. If you want to analyze your code more thoroughly, turn on the C4265 warning.
P.S. Unfortunately, always declaring a destructor virtual is not a good programming practice. It leads to additional overhead costs, since the class has to store a pointer to the virtual function table.
P.P.S. The related diagnostic rule is V689.
Additional resources:
- Wikipedia. Virtual method table.
- Wikipedia. Virtual function.
- Wikipedia. Destructor.
- Discussion on Stack Overflow. When to use virtual destructors?
- The Old New Thing. When should your destructor be virtual?
This diagnostic is classified as:
|
You can look at examples of errors detected by the V599 diagnostic. |