Last time we gave a brief introduction on virtual methods and method overriding. We also mentioned polymorphism and the so-called substitution principle which explains how parent and child objects can be interchanged in a program. These are things which cannot be learned separately - they all form the very basis of object-oriented programming and the C++ language. It is important to learn them thoroughly and understand how they are supposed to be used in programs. This is why we are going to pay special attention to this part of our C++ series.
The first step is a detailed explanation of the concept of virtual methods.
Let's consider this example:
cout << "Base";
class Derived: public Base
cout << "Derived";
Now, when we try to call the "correct"
basePtr = &d;
we can see that "Base" is printed (which is not what we wanted).
What happens is that our
basePtr points to the "base" part of the
Derived object. Hence, the compiler has no way to know it should, in fact, call the
print method of the derived class. A way to do this is provided by the virtual method mechanism.
Here is how it works: when a method is declared
virtual, its address is written into a so-called v-table. Internally, this means that a hidden member - an array of pointers to the overriden methods - is added to the base class. There are some rules concerning method overriding:
- Once a method is declared virtual, it cannot be redefined as non-virtual.
- In order for a virtual method to be overriden, the method signature must be the same.
- If there is at least one virtual method in the class, the destructor must also be declared virtual.
There are also situations (quite common) when the method we want to override doesn't even have a definition. These methods are called pure virtual functions, and this is the syntax of their declaration:
virtual void pureVirtualMethod()=0;
If there is at least one
pure virtual function in a class, the class is called abstract