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.