OOP C7 Polymorphism
Subtyping: subtype and supertype
A class defines a type.
- subtype: A type defined by a
derived class
. - supertype: A type defined by its
base class
.
RECALLL
The inheritance
relationship enables a derived class
to inherit features from its base class
with additional new features. A derived class
is a specialization of its base class
; every instance of a derived class
is also an instance of its base class
, but not vice versa.
Polymorphism
Polymorphism means that a variable of a supertype
can refer to a subtype
object. i.e
An object of a derived class
polymorphism can be used wherever its base class
object is used.
Conversions and upcasting
Conversions
Public Inheritance
should imply substitution.
- If B
is-a
A, you can use a B any where an A can be used. - if B
is-a
A, then everything that is true for A is also true of B. - Be careful if the substitution is not valid!
Given Derived
is derived from Base
, serval ways:
1 |
|
Upcasting, 向上造型
-
Upcasting is to regard an object of the
derived class
as an object of thebase class
. -
Upcasting is the act of converting from a
Derived reference
orpointer
to abase class reference
orpointer
.1
2
3
4
5
6
7/* Now give the Manager derived from Employee */
/* the Member function Print is not virtual. It is redefined in the Manager class.*/
Manager pete( "Pete", "444-55-6666", "Bakery");
Employee* ep = &pete; // Upcast
Employee& er = pete; // Upcast
ep -> print(cout); //perform in base class version
er.print(cout);
Virtual Functions and Dynamic Binding
Virtual Functions
A function can be implemented in several classes along the inheritance chain
. Virtual functions enable the system to decide which function is invoked at runtime based on the actual type of the object.
The keyword virtual
means that there may be other functions with the same name in the inheritance chain
.
- If a function is defined
virtual
in abase class
, it is automaticallyvirtual
in all itsderived classes
. That’s to sayvirtual
need not be added in the function declaration in thederived class
.
1 |
|
1 |
|
Dynamic Binding
The capability of determining which function to invoke at runtime is known as dynamic binding.
In C++, redefining
a virtual function
in a derived class
is called overriding a function.
static binding vs. dynamic binding
①Matching a function signature and ②binding a function implementation are two separate issues.
static binding
The declared type of the variable(i.e
static type) decides which function to match at compile time. The compiler finds a matching function according to parameter type, number of parameters, and order of the parameters
at compile time.
dynamic binding
A virtual function
may be implemented in several derived classes
. C++ dynamically binds the implementation of the function at runtime, decided by the actual class of the object referenced by the variable( i.e
dynamic type).
virtual
is the only symbol to generate a dynamic bindging
.
function type | binding type | example |
---|---|---|
free function | static | func() |
member function by obj | static | obj.func() |
member function by ref | static | ref.func() |
member function by pointer | static | p -> func() |
virtual function by ref | dynamic | ref.vfunc() |
virtual function by pointer | dynamic | p -> vfunc() |
- Static function are faster to execute.
- If a function defined in a base class needs to be
redefined
in its derived classes, you should define itvirtual
to avoid confusions and mistakes. - On the other hand, if a function will not be
redefined
, it is more efficient not to declare itvirtual
, because more time and system resource are required to bind virtual functions dynamically at
runtime.
- polymorphic type: a class with a
virtual function
. - Polymorphic variables:
Pointers
orreference
variables of objects. They can hold objects of thedeclared type
, or ofsubtypes
of thedeclared type
.
How virtuals work?
Example
1 |
|
Then, give the instances of the classes.
1 |
|
The output is
1 |
|
1 |
|
The output is
1 |
|
Virtual pointer and virtual table
Polymorphic variables
has virtual pointer, which points to virtual table. All virtual function pointers are stored in virtual table
.
virtual pointer
is only initialized in the initialize list of constructor and never changes again!
Virtual destructors
Please always make destructors virtual since all classes might be inherited.
Overriding
Overriding redefines the body of a virtual function.
- Superclass and subclass define methods with the same signature.
- Each has access to the fields of its class.
- Superclass satisfies static type check.
- The Relaxation:
1 |
|
Overloading virtual functions
If an overloaded function is overrided, then all of the variants should be overrided ! Or functions that are not overrided
will be hidden.
1 |
|
- Never redefine an inherited non-virtual function:
- Non-virtuals are statically bound
- No dynamic dispatch!
- Never redefine an inherited default parameter value: They’re statically bound too!