CXX.CWARN.DTOR.NONVIRT
Destructors should be declared as virtual.
To not so may lead to unexpected behaviour when using a base class handle to delete any derived class.
Vulnerability and risk
Derived classes may allocate memory or hold reference to other resources that will need to be cleaned up when the object is destroyed. If you do not give your interfaces/abstract classes virtual destructors, then every time you delete a derived class instance via a base class handle your derived class' destructor will not be called, which can lead to potential memory or resource leaks.
Mitigation and prevention
Always declare desctructors as virtual.
Example
class Base
{
// some virtual methods
};
class Derived : public Base
{
~Derived()
{
// Do some important cleanup
}
}
Base *b = new Derived();
// use b
delete b; // Here's the problem!
Since Base's destructor is not virtual and b is a Base* pointing to a Derived object, delete b has undefined behaviour. In most implementations, the call to the destructor will be resolved like any non-virtual code, meaning that the destructor of the base class will be called but not the one of the derived class, resulting in resources leak.