Let's suppose there are two classes: Base
and Derived
struct Base
{
Base() {}
virtual void foo() = 0;
virtual ~Base()
{
std::cout << "Base descructor" << std::endl;
}
};
struct Derived : Base
{
int *i;
Derived(int i_): Base(), i(new int[i_]) {}
virtual void foo() override
{
std::cout << "foo" << std::endl;
}
virtual ~Derived()
{
std::cout << "Derived descructor" << std::endl;
delete [] i;
}
};
Pure virtual functions
If Derived
doesn't override the foo
function you can create an instance of the Derived
class. When you try, your code will not compile, because foo
is a pure virtual function.
error: invalid new-expression of abstract class type 'Derived'
note: because the following virtual functions are pure within 'Derived':
struct Derived : Base
Pure virtual functions are used to describe the interface.
Now about virtual destructors:
The ~
(tilda) sign is used to denote the class destructor. It
is a special method that is called when the object is destroyed.
A client creates an instance of Derived:
Base *instance = new Derived;
then this variable is used somehow and when you don't need the variable you need to free the memory:
delete instance;
Let's trace the calls:
Derived descructor
Base descructor
So you can see that both base and derived destructors are called and no memory leak is possible. But if you remove this virtual
keyword from the destructors
Base descructor
As you can see the descturtor of Derived is not called, so a memory leak exists (the array of Derived class don't get released).
Hence virtual constructors are useful when you work with objects through pointers.