3. Virtual Functions
Function Call Binding
• Connecting a function call to a function body is called
binding.
• When binding is performed before the program is run
(by the compiler and linker), it is called early or static
binding.
• When the binding is performed at runtime, based on
the object type, it is called late, dynamic or runtime
binding.
– To perform late binding, the language must provide some
mechanism through which late binding could be achieved.
– In C++, late binding is achieved through the use of virtual
functions and base class pointer (or reference) to point to the
derived class object.
Engr. Anwar, Foundation University (FUIEMS), Islamabad 3
4. Virtual Functions
Normal Member Functions Accessed with Pointers
#include <iostream>
using namespace std;
class Base {
public:
void show() { cout << "nBase Classn";}
};
class Derv1 : public Base {
public:
void show() { cout << "nDerived class 1n"; }
};
class Derv2 : public Base {
public:
void show() { cout << "nDerived class 2n"; }
};
Engr. Anwar, Foundation University (FUIEMS), Islamabad 4
5. Virtual Functions
Normal Member Functions Accessed with Pointers
void main() {
Derv1 dv1; // object of derived class 1
Derv2 dv2; // object of derived class 2
dv1.show(); // will display Derived class 1
dv2.show(); // will display Derived class 2
// Let's do the same with pointers
Base* ptr; // declare a pointer to the base class
ptr = &dv1; // put address of dv1 in pointer
ptr->show(); // execute show(), displays Base Class
ptr = &dv2; // put address of dv2 in pointer
ptr->show(); // execute show(), displays Base Class
}
Engr. Anwar, Foundation University (FUIEMS), Islamabad 5
6. Virtual Functions
Normal Member Functions Accessed with Pointers
• Refer to the program given in the last two slides. The Derv1 and
Derv2 classes are derived from class Base. Each of these classes
has a member function show().
• In main, we create objects of class Derv1 and Derv2, and a
pointer to the class Base.
• We then put the address of a derived class object in the base
class pointer. This is possible because pointers to objects of a
derived class are type compatible with pointers to objects of the
base class.
• However, we note by executing the program, that when the
statement ptr->show() is executed, the show () function in the
base class is executed.
• The compiler ignores the contents of the pointer ptr and chooses
the member function that matches with the type of the pointer
Engr. Anwar, Foundation University (FUIEMS), Islamabad 6
7. Virtual Functions
Virtual Member Functions Accessed with Pointers
#include <iostream>
using namespace std;
class Base {
public:
virtual void show() { cout << "nBasen";}
};
class Derv1 : public Base {
public:
void show() { cout << "nDerived class 1n"; }
};
class Derv2 : public Base {
public:
void show() { cout << "nDerived class 2n"; }
};
Engr. Anwar, Foundation University (FUIEMS), Islamabad 7
8. Virtual Functions
Virtual Member Functions Accessed with Pointers
void main() {
Derv1 dv1; // object of derived class 1
Derv2 dv2; // object of derived class 2
dv1.show(); // will display Derived class 1
dv2.show(); // will display Derived class 2
// Let's do the same with pointers
Base* ptr; // declare a pointer to the base class
ptr = &dv1; // put address of dv1 in pointer
ptr->show(); // displays Derived class 1
ptr = &dv2; // put address of dv2 in pointer
ptr->show(); // displays Derived class 2
}
Engr. Anwar, Foundation University (FUIEMS), Islamabad 8
9. Virtual Functions
Virtual Member Functions Accessed with Pointers
• Refer to the program given in the last two slides.
• In this case, the member functions of the derived class, not the
base class, are executed.
• The same functions call ptr->show(); executes different functions,
depending on the contents of ptr.
• Thus the compiler selects the function based on the contents of
the pointer ptr, not on the type of the pointer.
• In this particular case, the compiler doesn’t know what class the
contents of ptr may contain. It defers the decision until the
program is running.
• At runtime, when it is known what class is pointed to by ptr, the
appropriate version of draw() is called.
• This is late binding or dynamic binding.
Engr. Anwar, Foundation University (FUIEMS), Islamabad 9
10. Abstract Base Classes and
Concrete Classes
• An abstract class is often defined as one that will not be
used to create any objects, but exists only to act as a
base class of other classes.
– Since these classes are used as base classes in inheritance
situations, we normally refer to them as abstract base classes.
• Classes from which objects can be instantiated are
called concrete classes.
• A class is made abstract by declaring one or more its
virtual functions to be “pure”.
– A pure virtual function is one with an initializer of =0 in its
declaration, e.g.
virtual void show() = 0; // pure virtual function
Engr. Anwar, Foundation University (FUIEMS), Islamabad 10
11. Abstract Base Classes and
Concrete Classes …
• If a class is derived from a class with a pure virtual
function, and if no definition is supplied for that pure
virtual function in the derived class, then that virtual
function remains pure in the derived class.
Consequently, the derived class is also an abstract class.
• Attempting to instantiate an object of an abstract class
(i.e. a class that contains one or more pure virtual
functions) is a syntax error.
• A hierarchy does not need to contain any abstract
classes, but many good object-oriented systems have
class hierarchies headed by an abstract class.
• In some cases, abstract classes constitute the top few
levels of hierarchy.
Engr. Anwar, Foundation University (FUIEMS), Islamabad 11
12. Polymorphism
• Poly mean many and morph means forms – thus polymorphism
means to take up many forms.
• C++ enables polymorphism – the ability for objects of different
classes related by inheritance to respond differently to the same
message (i.e. member function call).
– For example, if class Rectangle is derived from class Quadrilateral, then
Rectangle object is more specific version of Quadrilateral object.
– An operation (such as calculating the perimeter or area) that can be
performed on an Quadrilateral object also can be performed on a
Rectangle object.
• Polymorphism is implemented via virtual functions.
– When a request is made through a base-class pointer (or reference) to use
a virtual function, C++ chooses the correct overridden function in the
appropriate derived class associated with the object.
Engr. Anwar, Foundation University (FUIEMS), Islamabad 12
13. Exploiting Inheritance
• What can be done with different classes related by
inheritance?
– Any child of a class, can be stored in a pointer to that of
parent class
• This is called polymorphism
Engr. Anwar, Foundation University
13
(FUIEMS), Islamabad
14. How does polymorphism work?
• When a base class pointer is used to
store one of it’s children, any method
declared in the base class can be called.
• However, any methods that are not
declared in the base class can not be
called.
Engr. Anwar, Foundation University
14
(FUIEMS), Islamabad
15. How does polymorphism work?
• By default when a function is called using the
base class pointer, the method called will be
the one defined in the base class not the child
being pointed at).
– This is often not what you want to have happen.
Engr. Anwar, Foundation University
15
(FUIEMS), Islamabad
16. Polymorphism Defined
• The ability to take on different forms.
• Ability for different objects to interpret functions
differently
• Manipulate objects of various classes, and invoke
methods on an object without knowing that
object’s type.
Engr. Anwar, Foundation University
16
(FUIEMS), Islamabad
17. Polymorphism
• - extending inheritance
• Polymorphism means using the same syntax to do
different things depending on the context
• Polymorphism describes the ability of one operation
to be called for various objects, which, in turn, may
react differently.
• In C++ context, this means that different classes can
react differently for the same function call.
Engr. Anwar, Foundation University
17
(FUIEMS), Islamabad
18. Polymorphism
• Why Is this Important?
– Allow subclasses to be treated like instances of their
super classes
– Flexible architectures and designs
• high-level logic defined in terms of abstract interfaces
• relying on the specific implementation provided by
subclasses
• subclasses can be added without changing high-level
logic
Engr. Anwar, Foundation University
18
(FUIEMS), Islamabad
19. Using Base Class Pointer
class Box
{
};
class Carton : public Box
{ };
class Contents
{ };
class CerealPack : public Carton, public Contents
{
};
Engr. Anwar, Foundation University
19
(FUIEMS), Islamabad
20. Using Base Class Pointer
CerealPack breakfast;
//You can store the address of the breakfast object in
any base pointer
Carton * pCarton = &breakfast;
Box * pBox=&breakfast;
Contents* pContents=&breakfast;
// but the reverse is not true
Engr. Anwar, Foundation University
20
(FUIEMS), Islamabad
21. Using Base Class Pointer
class Box
{
};
class Carton : public Box
{ };
class ToughPack : public Box
{ };
Engr. Anwar, Foundation University
21
(FUIEMS), Islamabad
22. Using Base Class Pointer
Carton acarton(10, 10 , 5);
Box * pBox=&acarton;
ToughPack hardcase(2, 2, 2)
pBox=&hardcase;
• The pointer at the time of its declaration
is called static type
• It also has a dynamic type, which varies
according to the type of object it points to.
Engr. Anwar, Foundation University
22
(FUIEMS), Islamabad
23. Polymorphism
• Static and dynamic binding
– In most programming languages and in most cases the
variables are bound to a specific type at compile time
• Static binding
– Dynamic binding
• The type of the variable can change at run time
• Using pointers to classes related by inheritance in C+
+
Engr. Anwar, Foundation University
23
(FUIEMS), Islamabad
24. Virtual Functions
• A virtual function is a function that is declared with
the keyword virtual in a base class and then redefined
by a derived class.
• When a virtual function is invoked by a base class
pointer, the type of object being pointed at
determines which version of the function is called.
• The keyword virtual is only required in the base class,
but many programmers use it in derived classes
simply to remind themselves that the function is
virtual.
Engr. Anwar, Foundation University
24
(FUIEMS), Islamabad
25. Virtual Functions
• Used to support polymorphism with pointers and
references
• Ensures derived class function definition is resolved
dynamically
• When you declare as virtual in a base class, you
indicate to the compiler that you want dynamic
binding for the function in any class that’s derived
from this base class
Engr. Anwar, Foundation University
25
(FUIEMS), Islamabad
26. Polymorphism
Ability to manipulate derived objects using the interface
defined in the base class
• Example:
class Employee {
public:
void CalcPay ();
};
class SalariedEmployee :public Employee{
public:
void CalcPay ();
};
Engr. Anwar, Foundation University
26
(FUIEMS), Islamabad
27. Example
Employee *ep;
ep = new SalariedEmployee;
Ep->CalcPay();
• Which function is called?
– The function in Employee is called
• To avoid that we have to declare CalcPay() as a virtual
function
Engr. Anwar, Foundation University
27
(FUIEMS), Islamabad
28. Polymorphism
Ability to manipulate derived objects using the interface
defined in the base class
• Example:
class Employee {
public:
virtual void CalcPay ();
};
class SalariedEmployee :public Employee{
public:
virtual void CalcPay ();
};
Engr. Anwar, Foundation University
28
(FUIEMS), Islamabad
29. Example
Employee *ep;
ep = new SalariedEmployee;
ep->CalcPay();
• Which function is called?
– The function in SalariedEmployee is called
Engr. Anwar, Foundation University
29
(FUIEMS), Islamabad
30. Example: Virtual Functions
class Employee {
public:
virtual void CalcPay ();
};
class SalariedEmployee :public Employee{
public:
virtual void CalcPay ();
};
• virtual specifier needs to appear in the base class
only.
Engr. Anwar, Foundation University
30
(FUIEMS), Islamabad
31. Examples
Employee *p0 = new Employee;
Employee *p1 = new SalariedEmployee;
p0->CalcPay(); // calls employee::CalcPay()
p1->CalcPay(); // calls SalariedEmployee::CalcPay()
Engr. Anwar, Foundation University
31
(FUIEMS), Islamabad
32. Requirements for Virtual
Functions
• Not every function can be declared virtual.
• Following functions cannot be virtual
– Non-member functions,
– Static member functions,
– Constructors, and
– Friend functions cannot be virtual.
Engr. Anwar, Foundation University
32
(FUIEMS), Islamabad
33. Requirements for Virtual
Functions
• For a function to behave virtually you must declare
and define it with the same name and parameter list
in any derived class as it has in the base class.
• If you have declared the base class function as const,
then you must declare the derived class function to be
const as well.
• The return type should also be the same
Engr. Anwar, Foundation University
33
(FUIEMS), Islamabad
34. Requirements for Virtual Functions
• If you try to use different parameters for
virtual function then the virtual function
mechanism will not work.
• The function in the derived class will
operate with static binding.
Engr. Anwar, Foundation University
34
(FUIEMS), Islamabad
35. Combinations of virtual and non-
virtual functions
• Non-virtual function can call virtual function
class Employee {
public:
void Display() const;
virtual void CalcPay ();
};
class SalariedEmployee : public Employee{
public:
void Display() const;
virtual void CalcPay ();
};
Engr. Anwar, Foundation University
35
(FUIEMS), Islamabad
36. Example
void Employee::Display()
{ cout<<“pay of emp”;
CalcPay();
};
void SalariedEmployee::Display()
{
cout<<“pay of salried emp”;
CalcPay();
};
Employee *p0 = new SalariedEmployee;
p0->Display();
// calls SalariedEmployee::CalcPay();
Engr. Anwar, Foundation University
36
(FUIEMS), Islamabad
37. Access Specifers in Virtual Functions:
Example
class Box{
public:
Box();
void showVolume() const;
virtual double volume() const;
public:
int length, width, height;
};
void Box::showVolume() const
{
cout<<“ Box usable volume is” <<volume()<<endl;
}
double Box::volume()
{
return length* base* height;
} Engr. Anwar, Foundation University
37
(FUIEMS), Islamabad
38. class ToughPack:: public Box{
public:
ToughPack();
protected:
double volume() const;
};
Double ToughPack : : volume() const
{
return 0.5* length* base* heigth; }
int main()
{ box mybox; ToughPack hardcase;
myBox. volume();
hardcase.volume(); //error
box *pbox=&mybox;
pbox->volume();
pbox=&hardcase;
pbox->volume() //correct
Engr. Anwar, Foundation University
38
} (FUIEMS), Islamabad
39. Using References with Virtual
Functions
class Biomolecule{
virtual int Mweight();
. void printMW(Biomolecule &bm){
}; cout<<“Molecular weight is:”
<<bm.Mweight();
class Protein: public Biomolecule { }
Public:
int Mweight(); int main( ){
. Protein p;
}; DNA d;
.
class DNA : public Biomolecule{ .
Public: .
int Mweight(); printMW(p);
}; printMW(d);
}
Engr. Anwar, Foundation University
39
(FUIEMS), Islamabad
40. Polymorphism vs. Inheritance
• Inheritance is required in order to achieve
polymorphism (we must have class hierarchies).
– Re-using class definitions via extension and redefinition
• Polymorphism is not required in order to achieve
inheritance.
– An object of class A acts as an object of class B (an
ancestor to A).
Engr. Anwar, Foundation University
40
(FUIEMS), Islamabad
41. Virtual functions
• Function of derived class is called even if you have
only a pointer to the base class
File.cpp
File.h
void Func1()
class Shape
{
{
Circle mycirc;
virtual void Draw();
Func2(&mycirc);
};
}
class Circle : public Shape
void Func2(Shape* s)
{
{
virtual void Draw();
s->Draw();
};
}
// calls Circle::Draw()
Engr. Anwar, Foundation University
41
(FUIEMS), Islamabad
42. How a virtual function works
Shape vtable Circle vtable
vfunc1 addr vfunc1 addr
vfunc2 addr vfunc2 addr
... ...
vfuncN addr vfuncN addr
mycirc
var1
...
varM
vtable ptr
Engr. Anwar, Foundation University
42
(FUIEMS), Islamabad
43. What is the penalty of a virtual
function?
• Space:
– one vtable per class with virtual function(s)
– one pointer per instance
• Time:
– one extra dereference if type not known at
compile time
– no penalty if type known at compile time
(ok to inline a virtual function)
Engr. Anwar, Foundation University
43
(FUIEMS), Islamabad
44. Pure virtual function
• Pure virtual function
– Function intentionally undefined
– Same penalty as regular virtual function
• Abstract class
class Shape {
virtual void Draw() = 0;
};
– Contains at least one pure virtual function
– Cannot instantiate; must derive from base class and override pure
virtual function
– Provides an interface
(separates interface from implementation)
Engr. Anwar, Foundation University
44
(FUIEMS), Islamabad
45. class A {
public:
Virtual Functions
A () {cout<<" A";}
• Used to support polymorphism
virtual ~A () {cout<<" ~A";} with pointers and references
}; • Declared virtual in a base class
class B : public A { • Can be overridden in derived class
public: – Overriding only happens when
B () :A() {cout<<" B";} signatures are the same
virtual ~B() {cout<<" ~B";} – Otherwise it just overloads the
}; function or operator name
int main (int, char *[]) { • Ensures derived class function
// prints "A B" definition is resolved dynamically
A *ap = new B; – E.g., that destructors farther down the
hierarchy get called
// prints "~B ~A" : would only
// print "~A" if non-virtual
delete ap;
return 0;
};
Engr. Anwar, Foundation University
45
(FUIEMS), Islamabad
46. class A {
public: Virtual Functions
void x() {cout<<"A:x";};
•
virtual void y() {cout<<"A:y";}; Only matter with pointer or reference
}; – Calls on object itself resolved statically
– E.g., b.y();
class B : public A { • Look first at pointer/reference type
public: – If non-virtual there, resolve statically
void x() {cout<<"B:x";}; • E.g., ap->x();
virtual void y() {cout<<"B:y";};
– If virtual there, resolve dynamically
};
• E.g., ap->y();
int main () { • Note that virtual keyword need not be
B b; repeated in derived classes
A *ap = &b; B *bp = &b; – But it’s good style to do so
b.x (); // prints "B:x" • Caller can force static resolution of a
b.y (); // prints "B:y" virtual function via scope operator
bp->x (); // prints "B:x" – E.g., ap->A::y(); prints “A::y”
bp->y (); // prints "B:y"
ap.x (); // prints "A:x"
ap.y (); // prints "B:y"
return 0;
};
Engr. Anwar, Foundation University
46
(FUIEMS), Islamabad
47. class A {
public: Pure Virtual Functions
virtual void x() = 0;
virtual void y() = 0;
}; • A is an Abstract Base Class
– Similar to an interface in Java
class B : public A {
public:
– Declares pure virtual functions (=0)
virtual void x(); • Derived classes override pure virtual
}; methods
– B overrides x(), C overrides y()
class C : public B {
public: • Can’t instantiate class with declared
virtual void y(); or inherited pure virtual functions
};
– A and B are abstract, can create a C
int main () { • Can still have a pointer to an
A * ap = new C; abstract class type
ap->x (); – Useful for polymorphism
ap->y ();
delete ap;
return 0;
};
Engr. Anwar, Foundation University
47
(FUIEMS), Islamabad
48. Early binding
• The term early binding means resolving a function
call at compile-time.
• Examples of early binding include normal function
calls and overloaded function calls.
•
• Early binding is used when all of the information
needed to call a function is known at compile-time.
Engr. Anwar, Foundation University
48
(FUIEMS), Islamabad
49. Late binding
• The term late binding means resolving a function call
at run-time.
• Late binding is used when some of the information
needed to call a function is not known until run-time.
• Virtual function calls are an example of late binding.
• The decision on which derived class function to call is
made at run time
Engr. Anwar, Foundation University
49
(FUIEMS), Islamabad
50. Summary: Tips on Polymorphism
• Push common code and variables up into base classes
• Use public inheritance for polymorphism
• Polymorphism depends on dynamic typing
– Use a base-class pointer or reference if you want
polymorphism
– Use virtual member functions for dynamic overriding
• Use private inheritance only for encapsulation
• Use abstract base classes to declare interfaces
• Even though you don’t have to, label each virtual
method (and pure virtual method) in derived classes
Engr. Anwar, Foundation University
50
(FUIEMS), Islamabad