basics of polymorphism
e.g. invoking methods using an instance of Base class which belongs to Derived class. demolist11_1
1 |
|
Line 32 passes TunaOne as a parameter to Method FishSwim() that interprets it as a reference Fish &. The output as follow:
1 | tuna can swim |
Apparently, FishSwim doesn't care if the object sent was a Tuna, handles it as a Fish and invokes Fish::Swim().
polymorphic behavior implemented using virtual functions
Syntax:
1 | class Base |
use of keyword virtual means that the compiler ensure that any overriding variant of the requested base class method is invoked .
e.g The effect of declaring Fish::Swim as a virtual method
1 |
|
output
1 | tuna can swim |
The output it produces dramatically different, Fish::Swim has not been invoked because of the presence of overriding variants Tuna::Swim that has priority over Fish::Swim() because the latter has declared as a virtual function.
need for virtual destructor
What happen when a function calls operator delete using a pointer type Base* which actually points to an instance of type Derived?
e.g. A function that invoke operator delete on Base* demolist11_3
1 |
|
Output
1 | allocate memory for Tuna object |
Note that in line 40 while Fish and Tuna were both constructed on the free store due to new, the destructor of Tuna was not invoked during the delete. The flaw means that the destructor of a deriving class that has been instantiated on the free store using new would not be invoked if delete is called using a pointer of type Base*. To avoid this problem, using virtual destructor.
e.g. using virtual destructors to ensure that the destructors in derived classes are invoked when deleting a pointer of type Base*.
modifying demolist11_3 to the following in line 11
1 | virtual ~Fish() |
output
1 | allocate memory for Tuna object |
Note that this small change resulted in the compiler essentially executing Tuna::~Tuna() in addition to Fish::~Fish(), when operator delete was invoked on Fish which actually pointed to Tuna.
Always declare the base destructor as virtual:
1 | class Base |
This ensures that one with a pointer Base* cannot invoke delete in a way that instances of derived class are not correctly destroyed.
abstract base classes and pure virtual function
pure virtual method Syntax
1 | class AbstractBase |
DoSomething() need to be implemented by the class which derived from AbstractBase. That is shown in the following:
1 | class Derived : public AbstractBase |
class Fish as an abstract base class for Tuna demolist11_6
1 |
|
Abstract Base Classes are often called ABCs
if uncomment line 26, error occur as shown. Line 19-22 demonstrates that even if an ABCs can not be instantiated, you can use it as a reference or a pointer.