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.