Professional Documents
Culture Documents
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
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);
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.
Class A
Error!
Class B Class C
Class D
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
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
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();
// 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
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 ___________
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
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
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
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