Following this question, I\'m wondering why a struct\\class in C++ has to have a virtual method in order to be polymorphic.
Forcing a virtual destructor makes sense,
A C++ design philosophy is that "you don't pay for what you don't use". You might already know that a virtual
function incur some overhead as a class has to maintain a pointer to its implementation. In fact, an object contains a reference to a table of function pointers called the vtable.
Consider the following example:
class Base
{
public:
virtual f() { /* do something */ }
};
class Derived : public Base
{
public:
virtual f() { /* do something */ }
};
Base* a = new Derived;
a->f(); // calls Derived::f()
Note that the variable a
points to a Derived
object. As f()
is declared virtual
the vtable of a
will contain a pointer to Derived::f()
and that implementation is executed. If f()
is not virtual
, the vtable will be empty. So Base::f()
is executed as the type of a
is Base
.
A destructor behaves just like other member functions. If the destructor is not virtual
, only the destructor in the Base
class will be called. This might lead to memory/resource leaks if the Derived
class implements RAII. If a class is intended to be sub-classed, its destructor should be virtual
.
In some languages like Java all methods are virtual. So even objects that are not intended to be polymorphic will consume memory for maintaining the function pointers. In other words, you are forced to pay for what you don't use.
Without any virtual method, there is no need to maintain a virtual pointer (abbreviated as vptr) for every object of the class. The virtual pointer is a mechanism for resolving virtual method calls at runtime; depending on the object's class, it might point to different virtual method tables (abbreviated as vtable) that contain the actual adresses of virtual methods.
So by checking to what vtable does the vptr point to, compiler can determine object's class, for example in dynamic_cast
. Object without the vptr cannot have its type determined this way and is not polymorphic.