You are on page 1of 17

Object Oriented Programming – C++ Unit 8

Unit 8 Multiple Inheritance and Virtual Functions


and Polymorphism
Structure:
8.1 Introduction
Objectives
8.2 Introduction to Multiple Inheritance
8.3 Introduction to Virtual Functions
8.4 Introduction to Polymorphism
8.5 Summary
8.6 Terminal Questions
8.7 Answers

8.1 Introduction
You can derive a class from any number of base classes. Deriving a class
from more than one direct base class is called multiple inheritance. Virtual
functions are special member functions of a class which may be re-defined
in the derived classes. It is used to give specific meaning to the base class
member function with respect to the derive class. Virtual functions can be
thought of as a function name reserved in the bas class which may be re-
defined in the derived classes as per the need so that every derived class
has the same function that performs specific (as redefined in the derived
class) action. Polymorphism refers to the ability to call different functions by
using only one type of function call. In this unit we are going to discuss in
detail about the virtual functions and polymorphism with appropriate
example.
Objectives:
After studying thus unit you should be able to:
 implement multiple inheritance
 explain the concept of virtual function
 role of abstract class in OOPS
 brief the polymorphism concepts

8.2 Introduction to Multiple Inheritance


We have learnt in the last unit the concept of inheritance. We will explore in
detail the concept of multiple inheritance and the ambiguities that might

Sikkim Manipal University Page No.: 135


Object Oriented Programming – C++ Unit 8

arise in multiple inheritance. Multiple Inheritance is the process of inheriting


a class from more than one parent class. This would be required in several
instances where you would like to have the functionalities of several
classes . This is also extensively used in class libraries.
The syntax for implementing multiple inheritance is similar to single
inheritance. Let us suppose, there are two classes A and B, you want to
derive a class C from A and B. The syntax of class definition will be as
follows:
class C : public A, public B
{
};
Let us implement a program where there are two classes namely student
and employee. We will derive a class manager from the above two classes
and see how member functions and constructors are implemented in
multiple inheritance.
//multiple.cpp
# include<iostream.h>
# include<string.h>
# include<conio.h>
class student
{ protected:
char qual[6]; // highest degree earned
int percent; // percentage score in the last degree
public:
student()
{ strcpy(qual, “”); percent=0;}
student(char ch[6], int p)
{ strcpy(qual, ch); percent=p;}
void display()
{ cout<<endl<<”Qualification”<<qual;
cout<<endl<<”Score”<<percent;
}} ;
class employee {
protected:
int empno;
char ename[25];
Sikkim Manipal University Page No.: 136
Object Oriented Programming – C++ Unit 8

public:
employee()
{ empno=0;
strcpy(ename,"");
}
employee(int n, char ch[25])
{ empno=n;
strcpy(ename,ch);
}
void display()
{cout<<endl <<"Emp Code:"<<empno;
cout<<endl <<"Name:"<<ename;
}
};
class manager: public employee, public student
{
protected:
float basic;
float hra;
public:
manager():employee(),student()
{ basic=0.0; hra=0.0;}
manager(int n,char ch[25], char ch1[6], int p, float i, float j): employee(n,ch),
student(ch1,p)
{ basic=i; hra=j;}
void display()
{ employee::display();
student::display();
cout<<endl <<"Basic"<<basic;
cout<<endl <<"HRA"<<hra;
}
};
void main()
{
clrscr();
manager m1(205, “pawan”, “MBA”, 80, 40000.00, 5000.00);

Sikkim Manipal University Page No.: 137


Object Oriented Programming – C++ Unit 8

m1.display();
getch();
}
You can see in the above program, that the derived class constructors calls
both the parent class constructors. This is because every object of the
derived class has its own copy of parent data members. Therefore it is
required to initialize them as well. The parent class member functions are
invoked using the scope resolution operator as shown in the display function
of the manager class.
The output of the above program will be
Emp Code:205
Name:pawan
Qualification MBA
Score 80
Basic 40000
HRA 5000
Even though implementation of multiple inheritance is simple, there are
several type of ambiguities that might arise in its implementation. Let us
suppose there are two parent classes A and B. Class C has been derived
from A and B. There is a function f1() defined in both the parent classes but
f1() has not been defined in the child class. When the child class object
(objc) tries to access the function f1() through a statement objc.f1(), there is
compiler error. This is because the statement is ambiguous because the
compiler will not be able to figure out which parent’s f1() function have to be
called. The ambiguity can be resolved by prefixing the parent class name
followed by scope resolution operator before the function name. The
following statement would resolve the ambiguity.
objc.A::f1();
The above statement implies that use the function f1() of class A. Another
solution would be to introduce a dummy function f1() in Class C and invoke
the parent functions whichever applicable.
Another common ambiguity raised is in the case of diamond inheritance.
Diamond inheritance is a situation as shown in figure 8.1, arises when both
the parent classes have been derived from a single parent class.

Sikkim Manipal University Page No.: 138


Object Oriented Programming – C++ Unit 8

Class A
Error!

Class B Class C

Class D

Fig. 8.1: Diamond Inheritance


class A
{protected:
int a;};
class B : public parent
{}
class C: public parent
{}
class D : public B, public C
{ public:
int f1()
return a; // ambiguous
}
Imagine the above situation where there is a parent class A with a protected
data member a. Two child classes B and C are derived publicly from A.
Class D is derived both from B and C publicly. The compiler complains
when the grandchild class D tries to access the member a of the parent
class A. This ambiguity arises because when classes B and C are derived
from A, each inherits a copy of A called subobject and contains own copy of
parent data. The ambiguity arises for the grandchild in resolving which copy
of the child class subobject to be accessed.
The solution for this is virtual base class. By making classes B and C as
virtual classes, the two classes will share a common subobject and will
result in resolving the ambiguity as shown below.
class A
{protected:

Sikkim Manipal University Page No.: 139


Object Oriented Programming – C++ Unit 8

int a;};
class B : virtual public A
{}
class C: virtual public A
{}
class D : public B, public C
{ public:
int f1()
return a; //only one copy of the parent
}
Self Assessment Questions
1. In case of multiple inheritance, the child class has a copy of data of all the
parent classes. True/False
2. The problem of diamond inheritance ambiguity is resolved by declaring
the child classes as ____________
3. In multiple inheritance if the both the parent class (A and B) have same
function and child class (C) does not have that function, then the which
function is called
a. Class A
b. Class B
c. Have to be specified explicitly
d. No function will be called

8.3 Introduction to Virtual Functions


Virtual means existing in effect but not in reality. Virtual functions are
primarily used in inheritance. Let us suppose you have a class base as
shown in the following program and two classes derv1 and derv2 are
publicly derived from class base. You would like to create a pointer that
points to any of the derived class objects. If you create a pointer of derv1,
then it can point to derv1 object only. Compiler will complain if you assign
any other object is assigned to the pointer. The solution is to create a
pointer to Base class.
// objectptr.cpp
# include <iostream.h>
class base
{ public:
Sikkim Manipal University Page No.: 140
Object Oriented Programming – C++ Unit 8

void show()
{cout<<“base”<<endl;}};
class derv1:public base
{ public:
void show()
{cout<<“derv1”<<endl;}};
class derv2: public base
{ public:
void show()
{cout<<“derv2”<<endl;}};
void main()
{
derv1 dv1;
derv2 dv2;
base *ptr;
ptr=&dv1;
ptr->show();
ptr=&dv2;
ptr->show();
}
The output of the above program will be surprisingly:
base
base
Even though the address of derived classes is assigned to the pointer, the
compiler executes the base class function. However, if the base class
function is made virtual, we get the desired result. In the following program
we have made the base class function show() as virtual function by prefixing
with the keyword virtual.
//virtual.cpp
# include <iostream.h>
class base
{ public:
virtual void show() // virtual function
{cout<<“base”<<endl;}};
class derv1:public base
{ public:
Sikkim Manipal University Page No.: 141
Object Oriented Programming – C++ Unit 8

void show()
{cout<<“derv1”<<endl;}};
class derv2: public base
{ public:
void show()
{cout<<“derv2”<<endl;}};
void main()
{
derv1 dv1;
derv2 dv2;
base *ptr;
ptr=&dv1;
ptr->show();
ptr=&dv2;
ptr->show();
}
By declaring the base class function as virtual, we now get the output as:
derv1
derv2
In the above program, depending on the contents in the pointer, the
compiler decides which class function to call during runtime. This is known
as late binding or dynamic binding.
Virtual functions are for just name sake and will not be executed many a
times. If the virtual function has no specific role in the base but just declared
for enabling the derived class objects access through pointers, the function
can be declared as a pure virtual function. A pure virtual function is one
which does not have any body. Virtual functions declared by equating it to
zero as shown below:
virtual void show()=0;
In inheritance, many a times you would create a class just for grouping data
or functionality but the class does not have any instances of its own. Such
class which does not have any objects is known as abstract classes. For
example, there is a class known as employee and there are many classes
derived from this class such as manager, worker etc. In the program, the

Sikkim Manipal University Page No.: 142


Object Oriented Programming – C++ Unit 8

employee class brings together the common data and functions to all the
subclasses and to avoid coding same functionality in each and every class.
Here employee class is the abstract class. An abstract class is a class that
is designed to be specifically used as a base class. An abstract class
contains at least one pure virtual function. You declare a pure virtual
function by using a pure specifier (= 0) in the declaration of a virtual member
function in the class declaration. The following is the example of an abstract
class.
class AB {
public:
virtual void f() = 0;
};
Function AB::f is a pure virtual function. A function declaration cannot have
both a pure specifier and a definition. For example, the compiler will not
allow the following:
struct A {
virtual void g() { } = 0;
};
You cannot use an abstract class as a parameter type, a function return
type, or the type of an explicit conversion, nor can you declare an object of
an abstract class. You can, however, declare pointers and references to an
abstract class. The following example demonstrates this:
struct A {
virtual void f() = 0;
};

struct B : A {
virtual void f() { }
};

// Error:
// Class A is an abstract class
// A g();

Sikkim Manipal University Page No.: 143


Object Oriented Programming – C++ Unit 8

// Error:
// Class A is an abstract class
// void h(A);
A& i(A&);
int main() {

// Error:
// Class A is an abstract class
// A a;
A* pa;
B b;
// Error:
// Class A is an abstract class
// static_cast<A>(b);
}
Class A is an abstract class. The compiler would not allow the function
declarations A g() or void h(A), declaration of object a, nor the static cast of
b to type A. Virtual member functions are inherited. A class derived from an
abstract base class will also be abstract unless you override each pure
virtual function in the derived class. For example:
class AB {
public:
virtual void f() = 0;
};
class D2 : public AB {
void g();
};
int main() {
D2 d;
}
The compiler will not allow the declaration of object d because D2 is an
abstract class; it inherited the pure virtual function f()from AB. The compiler

Sikkim Manipal University Page No.: 144


Object Oriented Programming – C++ Unit 8

will allow the declaration of object d if you define function D2::g(). Note that
you can derive an abstract class from a non-abstract class, and you can
override a non-pure virtual function with a pure virtual function. You can call
member functions from a constructor or destructor of an abstract class.
However, the results of calling (directly or indirectly) a pure virtual function
from its constructor is undefined. The following example demonstrates this:
struct A {
A() {
direct();
indirect();
}
virtual void direct() = 0;
virtual void indirect() { direct(); }
};
The default constructor of A calls the pure virtual function direct() both
directly and indirectly (through indirect()).The compiler issues a warning for
the direct call to the pure virtual function, but not for the indirect call.
Self Assessment Questions
4. Base class functions which does not have any body is known as
_______.
5. The process of deciding which class function to be called during runtime
is known as _______________________
6. The classes which do not have any objects are known as ___________

8.4 Introduction to Polymorphism


Virtual functions in C++ are important to implement the concept of
polymorphism. Polymorphism means same content but different forms. In
C++, polymorphism enables the same program code calling different
functions of different classes. Imagine a situation where you would like to
create a class shape and derive classes such as rectangle, circle, triangle
etc. Let us suppose each of the classes has a member function draw() that
causes the object to be drawn on the screen. You would like to write a
common code as following so that you can draw several of these shapes
with same code and the shape to be drawn is decided during runtime:

Sikkim Manipal University Page No.: 145


Object Oriented Programming – C++ Unit 8

Shape *ptrarr[100]
for (int j=0;j<n;j++)
Ptrarr[j]->draw();
This is an very desirable capability that completely different functions are
executed by same function call. If the ptrarr is pointing to a rectangle, a
rectangle is drawn. If it is pointint to circle, circle is drawn.
This is exactly what is polymorphism. However to implement this approach
several conditions should be met. Firstly, all the classes rectangle, circle,
triangle should be derived from a single class (Here it is shape class).
Secondly, the draw() function must be declared as virtual in the base class
(in the shape class).
Operator overloading is, a type of polymorphism which allows the same
operators to behave differently with different datatypes/operands.
Once an application is written using the concept of polymorphism, it can
easily be extended, providing new objects that conform to the original
interface. It is unnecessary to recompile original programs by adding new
types. Only re-linking is necessary to exhibit the new changes along with the
old application. This is the greatest achievement of C++ object-oriented
programming. In programming language, there has always been a need for
adding and customizing. By utilizing the concept of polymorphism, time and
work effort is reduced in addition to making future maintenance easier.
 Helps in reusability of code.
 Provides easier maintenance of applications.
 Helps in achieving robustness in applications.
Types of Polymorphism: C++ provides three different types of
polymorphism.
 Virtual functions
 Function name overloading
 Operator overloading

In addition to the above three types of polymorphism, there exist other kinds
of polymorphism:
 run-time
 compile-time
 ad-hoc polymorphism
 parametric polymorphism

Sikkim Manipal University Page No.: 146


Object Oriented Programming – C++ Unit 8

run-time:
The run-time polymorphism is implemented with inheritance and virtual
functions.
compile-time: The compile-time polymorphism is implemented with
templates.
ad-hoc polymorphism: If the range of actual types that can be used is
finite and the combinations must be individually specified prior to use, this is
called ad-hoc polymorphism.
parametric polymorphism: If all code is written without mention of any
specific type and thus can be used transparently with any number of new
types it is called parametric polymorphism.
In general, there are two main categories of Polymorphism:
 Ad Hoc Polymorphism
 Pure Polymorphism

Overloading concepts fall under the category of Ad Hoc Polymorphism and


Virtual methods. Templates or parametric classes fall under the category of
Pure Polymorphism.
Self Assessment Questions
7. A pointer to a base class can point to the objects of a derived class.
True/False
8. If there is a pointer p, to the objects of a base class and it contains the
address of an object of a derived class, and both classes contain a
virtual member function, ding(), then the statement p->ding(); will cause
the version of ding() in the ________________ class to be executed
9. Polymorphism in C++ is implemented through ________________.

8.5 Summary
Inheritance has to be implemented with care especially when it is multiple
inheritance. Multiple inheritance creates ambiguity in situation where the
derived class does not implement the function implemented in both the
parent class and also in case of diamond inheritance. Virtual base class
helps in resolving the ambiguity. Virtual functions in base class helps to

Sikkim Manipal University Page No.: 147


Object Oriented Programming – C++ Unit 8

implement polymorphism in C++. Abstract classes are classes without any


objects.

8.6 Terminal Questions


1. Imagine a publishing company markets books and CD-ROMS. Create a
class called publication which stores title and price of a publication.
Derive two classes: book which adds a page count and CD-ROM which
adds playing time in minutes. Each of the three classes should have a
getdata() and putdata() function to get its data from the user and display
the data respectively. Write a main program that creates an array of
pointers to publication and in a loop, ask the user for data for book or
cdrom. When user has finished entering data, display all the data.
2. Explain the concept of virtual function
3. Discuss the role of polymorphism in OOPS

8.7 Answers
Self Assessment Questions
1. True
2. Virtual Base class
3. Have to be specified explicitly
4. Pure virtual functions
5. Late binding or dynamic binding
6. Abstract classes
7. True
8. Derived
9. Virtual functions
Terminal Questions
1. //publish.cpp
# include <iostream.h>
#include<conio.h>
class publication
{ protected:
char title[80];
float price;
public:
virtual void getdata()
Sikkim Manipal University Page No.: 148
Object Oriented Programming – C++ Unit 8

{ cout<<endl<<”enter title”; cin>>title;


cout<<endl<<”enter price”;cin>>price;
}
virtual void putdata()
{
cout<< endl<<”Title”<<title;
cout<<endl<<”Price”<<price;
}
};
class book: public publication
{
private:
int pages;
public:
void getdata()
{ publication::getdata();
cout<<endl<<”enter number of pages”; cin>>pages;
}
void putdata()
{
publication::putdata();
cout<< endl<<”Number of pages”<<pages;
}
};
class cdrom: public publication
{
private:
float time;
public:
void getdata()
{ publication::getdata();
cout<<endl<<”enter playing time”; cin>>time;
}
void putdata()
{
publication::putdata();

Sikkim Manipal University Page No.: 149


Object Oriented Programming – C++ Unit 8

cout<< endl<<”Playing time”<<time;


}
};
void main()
{
publication * ptr[10];
book* bptr;
cdrom* cptr;
char ch;
int n=0;
do
{
cout<<”Enter data for book or cdrom(b/c)”;
cin>>ch;
if (ch==’b’)
{
bptr= new book;
bptr->getdata();
ptr[n++]=bptr;
}
else
{cptr=new cdrom;
cptr->getdata();
ptr[n++]=cptr;
}
cout<<”enter another (y/n)”;
cin>>ch;
}while (ch==’y’);
for(int j=0;j<n;j++)
ptr[j]->putdata();
getch();
}
2. Virtual means existing in effect but not in reality. Virtual functions are
primarily used in inheritance. For more detail refer section 8.3.

Sikkim Manipal University Page No.: 150


Object Oriented Programming – C++ Unit 8

3. Polymorphism means same content but different forms. In C++,


polymorphism enables the same program code calling different functions
of different classes. For more details refer section 8.4.

Sikkim Manipal University Page No.: 151

You might also like