01-Polymorphism - Virtual Functions
01-Polymorphism - Virtual Functions
1 Virtual Functions
OBJECTIVES
Polymorphism in C++
Pointers to derived classes
Important point on inheritance
Introduction to virtual functions
Virtual destructors
More about virtual functions
Final comments
Applying polymorphism
2
BINDING
Connecting a function call to a function body is
called binding
When a function is called, which function
definition to invoke, when there are more than
one definitions
Types of binding
Static or Early binding
Dynamic or Late binding
3
POLYMORPHISM IN C++
2 types
Compile time polymorphism
Uses static or early binding
Example: Function, Operator overloading and Templates
4
POINTERS TO DERIVED CLASSES
C++ allows base class pointers to point to
derived class objects.
Let we have –
class base { … };
class derived : public base { … };
5
POINTERS TO DERIVED
CLASSES (CONTD.)
Using a base class pointer (pointing
to a derived class object) we can
access only those members of the
derived object that were inherited
from the base.
This is because the base pointer
has knowledge only of the base class.
It knows nothing about the members
added by the derived class.
6
POINTERS TO DERIVED
CLASSES (CONTD.)
class base { void main() {
public: base b1;
void show() { b1.show(); // base
cout << “base\n”; derived d1;
} d1.show(); // derived
}; base *pb = &b1;
class derived : public base { pb->show(); // base
public: pb = &d1;
void show() { pb->show(); // base
cout << “derived\n”; }
} All the function calls here
}; are statically bound
Show Code 7
POINTERS TO DERIVED CLASSES
(CONTD.) - SOLUTION
class base { void main() {
public: base b1;
virtual void show() { b1.show(); // base - (s.b.)
cout << “base\n”; derived d1;
} d1.show(); // derived – (s.b.)
}; base *pb = &b1;
class derived : public base { pb->show(); // base - (d.b.)
public: pb = &d1;
void show() { pb->show(); // derived
(d.b.)
cout << “derived\n”;
}
}
Show Code
};
Here, 8
s.b. = static binding
d.b. = dynamic binding
POINTERS TO DERIVED
CLASSES (CONTD.)
Whileit is permissible for a base class
pointer to point to a derived object, the
reverse is not true.
base b1;
derived *pd = &b1; // compiler error
We can perform a downcast with the
help of type-casting, but should use it
with caution ( see next )
9
POINTERS TO DERIVED
CLASSES (CONTD.)
Let we have –
class base { … };
class derived : public base { … };
class xyz { … }; // having no relation with “base” or “derived”
Then if we write –
1. base b_obj; base *pb; derived d_obj; pb = &d_obj; // ok
2. derived *pd = pb; // compiler error
3. derived *pd = (derived *)pb; // ok, valid downcasting
4. xyz obj; // ok
5. pd = (derived *)&obj; // invalid casting, no compiler error, but
may cause run-time error
6. pd = (derived *)&b_obj; // invalid casting, no compiler error,
but may cause run-time error
10
POINTERS TO DERIVED
CLASSES (CONTD.)
casting.
POINTERS TO DERIVED
CLASSES (CONTD.)
12
IMPORTANT POINT ON
INHERITANCE
In C++, only public inheritance supports the perfect
IS-A relationship.
In case of private and protected inheritance, we cannot
treat a derived class object in the same way as a base
class object
Public members of the base class becomes private or protected
in the derived class and hence cannot be accessed directly by
others using derived class objects
If we use private or protected inheritance, we cannot
assign the address of a derived class object to a base
class pointer directly.
We can use type-casting, but it makes the program logic and
structure complicated.
This is one of the reason for which Java only supports
public inheritance. 13
INTRODUCTION TO VIRTUAL
FUNCTIONS
A virtual function is a member function
that is declared within a base class and
redefined by a derived class.
The redefinition of a virtual function in a
derived class is usually called overriding.
It implements the “one interface, multiple
methods” philosophy that underlies
polymorphism.
The keyword virtual is used to designate
a member function as virtual.
Supports run-time polymorphism with the
help of base class pointers. 14
INTRODUCTION TO VIRTUAL
FUNCTIONS (CONTD.)
While redefining a virtual function in a
derived class, the function signature must
match the original function present in the
base class.
So, we call it overriding, not overloading.
When a virtual function is redefined by a
derived class, the keyword virtual is not
needed (but can be specified if the
programmer wants).
The “virtual”-ity of the member function
continues along the inheritance chain.
A class that contains a virtual function is 15
referred to as a polymorphic class.
INTRODUCTION TO VIRTUAL
FUNCTIONS (CONTD.)
18
VIRTUAL DESTRUCTORS (CONTD.)
19
Using non-virtual destructor
VIRTUAL DESTRUCTORS (CONTD.)
20
Using virtual destructor
MORE ABOUT VIRTUAL FUNCTIONS
Ifwe can omit the body of a virtual
function in a base class, we can use pure
virtual functions.
virtual ret-type func_name(param-list) = 0;
It makes a class an abstract class.
We cannot create any objects of such classes.
It forces derived classes to override it.
Otherwise they become abstract too.
21
MORE ABOUT VIRTUAL
FUNCTIONS (CONTD.)
Pure virtual function
Helps to guarantee that a derived class will
provide its own redefinition.
We can still create a pointer to an abstract
class
Because it is at the heart of run-time
polymorphism
When a virtual function is inherited, so it
is virtual nature.
We can continue to override virtual
functions along the inheritance hierarchy. 22
FINAL COMMENTS
Classes from which objects can be instantiated are
called concrete classes.
If a class has nothing but pure virtual functions, we
call it a pure abstract class
Run-time polymorphism is not automatically activated
in C++.
We have to use virtual functions and base class
pointers to enforce and activate run-time
polymorphism in C++.
But, in Java, run-time polymorphism is automatically
present as all non-static methods of a class are by
default virtual in nature.
We just need to use superclass references to point to subclass
objects to achieve run-time polymorphism in Java. 23
APPLYING POLYMORPHISM
Early binding
Normal functions, overloaded functions
Nonvirtual member and friend functions, Even
Templates also.
Resolved at compile time
Very efficient
But lacks flexibility
Late binding
Virtual functions accessed via a base class pointer
Resolved at run-time
Quite flexible during run-time
But has run-time overhead; slows down program
execution
24