0% found this document useful (0 votes)
25 views41 pages

Unit Four

This document provides course material for the Fundamentals of Programming, focusing on Inheritance and Polymorphism in C++. It covers key concepts such as types of inheritance (single, multiple, multilevel, hierarchical, hybrid), static members in C++, and includes example code snippets to illustrate these concepts. The notes serve as a guideline for students and emphasize the importance of referring to textbooks for comprehensive understanding.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
25 views41 pages

Unit Four

This document provides course material for the Fundamentals of Programming, focusing on Inheritance and Polymorphism in C++. It covers key concepts such as types of inheritance (single, multiple, multilevel, hierarchical, hybrid), static members in C++, and includes example code snippets to illustrate these concepts. The notes serve as a guideline for students and emphasize the importance of referring to textbooks for comprehensive understanding.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 41

Bansilal Ramnath Agrawal Charitable Trust’s

VISHWAKARMA INSTITUTE OF INFORMATION TECHNOLOGY


Department of Engineering &Applied Sciences

F. Y. B. Tech.
Course Material (A Brief Reference Version for Students)

Course: Fundamentals of Programming


Unit IV - Inheritance and Polymorphism
Disclaimer: These notes are for internal circulation and are not meant for commercial use. These notes are
meant to provide guidelines and outline of the unit. They are not necessarily complete answers to
examination questions. Students must refer reference/ text books; write lecture notes for producing
expected answer in examination. Charts/ diagrams must be drawn wherever necessary.
Unit IV - Inheritance and Polymorphism
Inheritance – Introduction, single inheritance, multiple inheritance, Static members in
C++, Scope resolution operator, inline functions, Polymorphism – Introduction, function
overloading, function overriding, virtual functions, Friend function.

Lecture 1: Introduction to Inheritance in C++ Programming

Lecture 2: Single Inheritance, Multiple Inheritances

Lecture 3: Static Members in C++, Scope Resolution Operator, Inline Function,

Lecture 4: Introduction to Polymorphism, Function Overloading

Lecture 5: Function Overriding, Virtual Functions

Lecture 6: Friend function


Inheritance in C++
The capability of a class to derive properties and characteristics from another class is called
Inheritance. Inheritance is one of the most important features of Object Oriented
Programming.
 Sub Class: The class that inherits properties from another class is called Sub class or
derived class
 Super Class: The class whose properties are inherited by sub class is called Base Class
or Super class.

The article is divided into following subtopics:


1. Why and when to use inheritance?
2. Modes of Inheritance
3. Types of Inheritance

Why and when to use inheritance?


Consider a group of vehicles. You need to create classes for Bus, Car and Truck. The methods
fuelAmount(), capacity(), applyBrakes() will be same for all of the three classes. If we create
these classes avoiding inheritance then we have to write all of these functions in each of the
three classes as shown in below figure:

You can clearly see that above process results in duplication of same code 3 times. This
increases the chances of error and data redundancy. To avoid this type of situation,
inheritance is used. If we create a class Vehicle and write these three functions in it and
inherit the rest of the classes from the vehicle class, then we can simply avoid the
duplication of data and increase re-usability. Look at the below diagram in which the three
classes are inherited from vehicle class:
Using inheritance, we have to write the functions only one time instead of three times as we
have inherited rest of the three classes from base class(Vehicle).

Implementing inheritance in C++:


For creating a sub-class which is inherited from the base class we have to follow the below
syntax.

Syntax:

class subclass_name : access_mode base_class_name


{
//body of subclass
};

Here, subclass_name is the name of the sub class, access_mode is the mode in which you
want to inherit this sub class for example: public, private etc. and base_class_name is the
name of the base class from which you want to inherit the sub class.

Note: A derived class doesn’t inherit access to private data members. However, it does
inherit a full parent object, which contains any private members which that class declares.

// C++ program to demonstrate implementation


// of Inheritance

#include <bits/stdc++.h>
using namespace std;
//Base class
class Parent
{
public:
int id_p;
};

// Sub class inheriting from Base Class(Parent)


class Child : public Parent
{
public:
int id_c;
};

//main function
int main()
{

Child obj1;

// An object of class child has all data members


// and member functions of class parent
obj1.id_c = 7;
obj1.id_p = 91;
cout << "Child id is " << obj1.id_c << endl;
cout << "Parent id is " << obj1.id_p << endl;

return 0;
}
Output:

Child id is 7
Parent id is 91

In the above program the ‘Child’ class is publicly inherited from the ‘Parent’ class so the
public data members of the class ‘Parent’ will also be inherited by the class ‘Child’.

Modes of Inheritance

 Public mode: If we derive a sub class from a public base class. Then the public
member of the base class will become public in the derived class and protected
members of the base class will become protected in derived class.
 Protected mode: If we derive a sub class from a Protected base class. Then both
public member and protected members of the base class will become protected in
derived class.
 Private mode: If we derive a sub class from a Private base class. Then both public
member and protected members of the base class will become Private in derived
class.

Note: The private members in the base class cannot be directly accessed in the derived
class, while protected members can be directly accessed. For example, Classes B, C and D all
contain the variables x, y and z in below example. It is just question of access.

// C++ Implementation to show that a derived class


// doesn’t inherit access to private data members.
// However, it does inherit a full parent object
class A
{
public:
int x;
protected:
int y;
private:
int z;
};

class B : public A
{
// x is public
// y is protected
// z is not accessible from B
};

class C : protected A
{
// x is protected
// y is protected
// z is not accessible from C
};

class D : private A // 'private' is default for classes


{
// x is private
// y is private
// z is not accessible from D
};
The below table summarizes the above three modes and shows the access specifier of the
members of base class in the sub class when derived in public, protected and private modes:
Types of Inheritance in C++
1. Single Inheritance:
In single inheritance, a class is allowed to inherit from only one class. i.e. one sub class is
inherited by one base class only.

Syntax:

class subclass_name : access_mode base_class


{
//body of subclass
};
// C++ program to explain
// Single inheritance
#include <iostream>
using namespace std;

// base class
class Vehicle {
public:
Vehicle()
{
cout << "This is a Vehicle" << endl;
}
};

// sub class derived from base class


class Car: public Vehicle{

};

// main function
int main()
{
// creating object of sub class will
// invoke the constructor of base classes
Car obj;
return 0;
}
Output:

This is a vehicle

2. Multiple Inheritance:
Multiple Inheritance is a feature of C++ where a class can inherit from more than one
classes, i.e. one sub class is inherited from more than one base classes.

Syntax:

class subclass_name : access_mode base_class1, access_mode


base_class2, ....
{
//body of subclass
};
Here, the number of base classes will be separated by a comma (‘, ‘) and access mode for
every base class must be specified.
// C++ program to explain
// multiple inheritance
#include <iostream>
using namespace std;

// first base class


class Vehicle {
public:
Vehicle()
{
cout << "This is a Vehicle" << endl;
}
};
// second base class
class FourWheeler {
public:
FourWheeler()
{
cout << "This is a 4 wheeler Vehicle" << endl;
}
};

// sub class derived from two base classes


class Car: public Vehicle, public FourWheeler {

};

// main function
int main()
{
// creating object of sub class will
// invoke the constructor of base classes
Car obj;
return 0;
}
Output:

This is a Vehicle
This is a 4 wheeler Vehicle
3. Multilevel Inheritance:
In this type of inheritance, a derived class is created from another derived class.

// C++ program to implement


// Multilevel Inheritance
#include <iostream>
using namespace std;

// base class
class Vehicle
{
public:
Vehicle()
{
cout << "This is a Vehicle" << endl;
}
};
class fourWheeler: public Vehicle
{ public:
fourWheeler()
{
cout<<"Objects with 4 wheels are vehicles"<<endl;
}
};
// sub class derived from two base classes
class Car: public fourWheeler{
public:
car()
{
cout<<"Car has 4 Wheels"<<endl;
}
};

// main function
int main()
{
//creating object of sub class will
//invoke the constructor of base classes
Car obj;
return 0;
}
Output:

This is a Vehicle
Objects with 4 wheels are vehicles
Car has 4 Wheels

4. Hierarchical Inheritance:
In this type of inheritance, more than one sub class is inherited from a single base class. i.e.
more than one derived class is created from a single base class.

// C++ program to implement


// Hierarchical Inheritance
#include <iostream>
using namespace std;
// base class
class Vehicle
{
public:
Vehicle()
{
cout << "This is a Vehicle" << endl;
}
};

// first sub class


class Car: public Vehicle
{

};

// second sub class


class Bus: public Vehicle
{

};

// main function
int main()
{
// creating object of sub class will
// invoke the constructor of base class
Car obj1;
Bus obj2;
return 0;
}
Output:

This is a Vehicle
This is a Vehicle
5. Hybrid (Virtual) Inheritance:
Hybrid Inheritance is implemented by combining more than one type of inheritance. For
example: Combining Hierarchical inheritance and Multiple Inheritance.
Below image shows the combination of hierarchical and multiple inheritances:

// C++ program for Hybrid Inheritance

#include <iostream>
using namespace std;

// base class
class Vehicle
{
public:
Vehicle()
{
cout << "This is a Vehicle" << endl;
}
};

//base class
class Fare
{
public:
Fare()
{
cout<<"Fare of Vehicle\n";
}
};

// first sub class


class Car: public Vehicle
{

};

// second sub class


class Bus: public Vehicle, public Fare
{

};

// main function
int main()
{
// creating object of sub class will
// invoke the constructor of base class
Bus obj2;
return 0;
}
Output:

This is a Vehicle
Fare of Vehicle
Static Members in C++
Defining static members in C++
Static members in a class in C++ can be defined using the static keyword. There is only one
copy of the static class member in memory, regardless of the number of objects of the class.
So the static member is shared by all the class objects.
The static class member is initialized to zero when the first object of the class is created if it
is not initialized in any other way.
A program that demonstrates the definition of the static class members is given as follows −
Example

#include <iostream>
using namespace std;

class Point{
int x;
int y;

public:
static int count;

Point(int x1, int y1){


x = x1;
y = y1;

count++;
}

void display(){
cout<<"The point is ("<<x<<","<<y<<")\n";
}
};

int Point::count = 0;

int main(void){
Point p1(10,5);
Point p2(7,9);
Point p3(1,2);

p1.display();
p2.display();
p3.display();

cout<<"\nThe number of objects are: "<<Point::count;


return 0;
}
The output of the above program is as follows −

The point is (10,5)


The point is (7,9)
The point is (1,2)

The number of objects are: 3

Now let us understand the above program.


The class Point has 2 data members x and y that constitute a point. There is also a static
member count that monitors the numbers of objects created of class Point. The constructor
Point() initializes the values of x and y and the function display() displays their values.
In the function main(), there are 3 objects created of class Point. Then the values of these
objects are displayed by calling the function display(). Then the value of count is displayed.
Static Data Members in C++
Static data members are class members that are declared using the static keyword. There is
only one copy of the static data member in the class, even if there are many class objects.
This is because all the objects share the static data member. The static data member is
always initialized to zero when the first class object is created.
The syntax of the static data members is given as follows −
static data_type data_member_name;
In the above syntax, static keyword is used. The data_type is the C++ data type such as int,
float etc. The data_member_name is the name provided to the data member.
A program that demonstrates the static data members in C++ is given as follows −
Example

#include <iostream>
#include<string.h>

using namespace std;


class Student {
private:
int rollNo;
char name[10];
int marks;
public:
static int objectCount;
Student() {
objectCount++;
}
void getdata() {
cout << "Enter roll number: "<<endl;
cin >> rollNo;
cout << "Enter name: "<<endl;
cin >> name;
cout << "Enter marks: "<<endl;
cin >> marks;
}

void putdata() {
cout<<"Roll Number = "<< rollNo <<endl;
cout<<"Name = "<< name <<endl;
cout<<"Marks = "<< marks <<endl;
cout<<endl;
}
};
int Student::objectCount = 0;
int main(void) {
Student s1;
s1.getdata();
s1.putdata();
Student s2;

s2.getdata();
s2.putdata();
Student s3;

s3.getdata();
s3.putdata();
cout << "Total objects created = " << Student::objectCount
<< endl;
return 0;
}
Output

The output of the above program is as follows −


Enter roll number: 1
Enter name: Mark
Enter marks: 78
Roll Number = 1
Name = Mark
Marks = 78

Enter roll number: 2


Enter name: Nancy
Enter marks: 55
Roll Number = 2
Name = Nancy
Marks = 55

Enter roll number: 3


Enter name: Susan
Enter marks: 90
Roll Number = 3
Name = Susan
Marks = 90
Total objects created = 3

In the above program, the class student has three data members denoting the student roll
number, name and marks. The objectCount data member is a static data member that
contains the number of objects created of class Student. Student() is a constructor that
increments object Count each time a new class object is created.
There are 2 member functions in class. The function getdata() obtains the data from the
user and putdata() displays the data.
In the function main(), there are three objects of class Student i.e. s1, s2 and s3. For each of
these objects getdata() and putdata() are called. At the end, the value of objectCount is
displayed.
When are static C++ class members initialized?
Static C++ class members can be defined using the static keyword. The static member in a
class is shared by all the class objects as there is only one copy of the static class member in
the memory, regardless of the number of objects of the class.
The static class member is initialized to zero when the first object of the class is created if it
is not initialized in any other way.
A program that demonstrates static class members in C++ is given as follows.
Example

#include <iostream>
using namespace std;
class Example {
public :
static int a;
int func() {
cout << "The value of static member a: " << a;
}
};
int Example::a = 20;
int main() {
Example obj;
obj.func();
return 0;
}
Output

The output of the above program is as follows.


The value of static member a: 20
Now let us understand the above program.
In the class Example, the static class member is a. The function func() displays the value of a.
In the function main(), an object obj of class Example is created. Then the function func() is
called that displays the value of a.
Static Function Members
By declaring a function member as static, you make it independent of any particular object
of the class. A static member function can be called even if no objects of the class exist and
the static functions are accessed using only the class name and the scope resolution
operator ::.
A static member function can only access static data member, other static member
functions and any other functions from outside the class.
Static member functions have a class scope and they do not have access to the this pointer
of the class. You could use a static member function to determine whether some objects of
the class have been created or not.
Let us try the following example to understand the concept of static function members −
#include <iostream>
using namespace std;

class Box {
public:
static int objectCount;

// Constructor definition
Box(double l = 2.0, double b = 2.0, double h = 2.0) {
cout <<"Constructor called." << endl;
length = l;
breadth = b;
height = h;

// Increase every time object is created


objectCount++;
}
double Volume() {
return length * breadth * height;
}
static int getCount() {
return objectCount;
}
private:
double length; // Length of a box
double breadth; // Breadth of a box
double height; // Height of a box
};

// Initialize static member of class Box


int Box::objectCount = 0;

int main(void) {
// Print total number of objects before creating object.
cout << "Inital Stage Count: " << Box::getCount() << endl;

Box Box1(3.3, 1.2, 1.5); // Declare box1


Box Box2(8.5, 6.0, 2.0); // Declare box2

// Print total number of objects after creating object.


cout << "Final Stage Count: " << Box::getCount() << endl;

return 0;
}
When the above code is compiled and executed, it produces the following result −
Inital Stage Count: 0
Constructor called.
Constructor called.
Final Stage Count: 2
Inline function in C++
Inline function is one of the important features of C++. So, let’s first understand why inline
functions are used and what is the purpose of inline function?
When the program executes the function call instruction the CPU stores the memory
address of the instruction following the function call, copies the arguments of the function
on the stack and finally transfers control to the specified function. The CPU then executes
the function code, stores the function return value in a predefined memory location/register
and returns control to the calling function. This can become overhead if the execution time
of function is less than the switching time from the caller function to called function (callee).
For functions that are large and/or perform complex tasks, the overhead of the function call
is usually insignificant compared to the amount of time the function takes to run. However,
for small, commonly-used functions, the time needed to make the function call is often a lot
more than the time needed to actually execute the function’s code. This overhead occurs
for small functions because execution time of small function is less than the switching time.
C++ provides an inline functions to reduce the function call overhead. Inline function is a
function that is expanded in line when it is called. When the inline function is called whole
code of the inline function gets inserted or substituted at the point of inline function call.
This substitution is performed by the C++ compiler at compile time. Inline function may
increase efficiency if it is small.

The syntax for defining the function inline is:


inline return-type function-name(parameters)
{
// function code
}

Remember, inlining is only a request to the compiler, not a command. Compiler can ignore
the request for inlining. Compiler may not perform inlining in such circumstances like:
1. If a function contains a loop. (for, while, do-while)
2. If a function contains static variables.
3. If a function is recursive.
4. If a function return type is other than void, and the return statement doesn’t exist in
function body.
5. If a function contains switch or goto statement.

Inline functions provide following advantages:

1. Function call overhead doesn’t occur.


2. It also saves the overhead of push/pop variables on the stack when function is called.
3. It also saves overhead of a return call from a function.
4. When you inline a function, you may enable compiler to perform context specific
optimization on the body of function. Such optimizations are not possible for normal
function calls. Other optimizations can be obtained by considering the flows of
calling context and the called context.
5. Inline function may be useful (if it is small) for embedded systems because inline can
yield less code than the function call preamble and return.

Inline function disadvantages:

1. The added variables from the inline function consumes additional registers, After in-
lining function if variables number which are going to use register increases than
they may create overhead on register variable resource utilization. This means that
when inline function body is substituted at the point of function call, total number of
variables used by the function also gets inserted. So the number of register going to
be used for the variables will also get increased. So if after function in lining variable
numbers increase drastically then it would surely cause an overhead on register
utilization.
2. If you use too many inline functions then the size of the binary executable file will be
large, because of the duplication of same code.
3. Too much in lining can also reduce your instruction cache hit rate, thus reducing the
speed of instruction fetch from that of cache memory to that of primary memory.
4. Inline function may increase compile time overhead if someone changes the code
inside the inline function then all the calling location has to be recompiled because
compiler would require to replace all the code once again to reflect the changes,
otherwise it will continue with old functionality.
5. Inline functions may not be useful for many embedded systems. Because in
embedded systems code size is more important than speed.
6. Inline functions might cause thrashing because inlining might increase size of the
binary executable file. Thrashing in memory causes performance of computer to
degrade.

The following program demonstrates the use of use of inline function.


#include <iostream>
using namespace std;
inline int cube(int s)
{
return s*s*s;
}
int main()
{
cout << "The cube of 3 is: " << cube(3) << "\n";
return 0;
}

Output:

The cube of 3 is: 27


Inline function and classes:
It is also possible to define the inline function inside the class. In fact, all the functions
defined inside the class are implicitly inline. Thus, all the restrictions of inline functions are
also applied here. If you need to explicitly declare inline function in the class then just
declare the function inside the class and define it outside the class using inline keyword.
For example:
class S
{
public:
inline int square(int s) // redundant use of inline
{
// this function is automatically inline
// function body
}
};

The above style is considered as a bad programming style. The best programming style is to
just write the prototype of function inside the class and specify it as an inline in the function
definition.

For example:

class S
{
public:
int square(int s); // declare the function
};

inline int S::square(int s) // use inline prefix


{

The following program demonstrates this concept:

#include <iostream>
using namespace std;
class operation
{
int a,b,add,sub,mul;
float div;
public:
void get();
void sum();
void difference();
void product();
void division();
};
inline void operation :: get()
{
cout << "Enter first value:";
cin >> a;
cout << "Enter second value:";
cin >> b;
}

inline void operation :: sum()


{
add = a+b;
cout << "Addition of two numbers: " << a+b << "\n";
}

inline void operation :: difference()


{
sub = a-b;
cout << "Difference of two numbers: " << a-b << "\n";
}

inline void operation :: product()


{
mul = a*b;
cout << "Product of two numbers: " << a*b << "\n";
}

inline void operation ::division()


{
div=a/b;
cout<<"Division of two numbers: "<<a/b<<"\n" ;
}

int main()
{
cout << "Program using inline function\n";
operation s;
s.get();
s.sum();
s.difference();
s.product();
s.division();
return 0;
}
Output:

Enter first value: 45


Enter second value: 15
Addition of two numbers: 60
Difference of two numbers: 30
Product of two numbers: 675
Division of two numbers: 3
Pointers to Class Members in C++
Just like pointers to normal variables and functions, we can have pointers to class member
functions and member variables.
In C++, a pointer holds the address of an object stored in memory. The pointer then simply
“points” to the object. The type of the object must correspond with the type of the pointer.
Defining a Pointer of Class type
 We can define pointer of class type, which can be used to point to class objects.
type *name; // points to a value of the specified type
 type refers to the data type of the object our pointer points to, and name is just the
label of the pointer. The * character specifies that this variable is in fact, a pointer.
Here is an example:
int *p; // integer pointer
string *q; // string pointer
 The & character specifies that we are storing the address of the variable succeeding
it.

 The * character lets us access the value.

Example 1:
#include <iostream>
using namespace std;

int main() {
int var = 10;
int *p;
p = &var; // p points to the address of var
cout << "The address stored in p: " << p << endl;
cout << "The value that points to: " << *p << endl;

*p = 15; // update the value of p


cout << "The new value of var is: " << var << endl; // var is
updated!

var = 20; // the value of var is updated


cout << "The new value of *p and var: " << *p; // p has been
updated as well!
}
Output:
The address stored in p: 0x7ffc2de9ddd4
The value that points to: 10
The new value of var is: 15
The new value of *p and var: 20
Example 2:
#include <iostream>
using namespace std;

class Simple
{
public:
int a=10;
};

int main()
{
Simple obj;
Simple* ptr; // Pointer of class type
ptr = &obj;

cout << "The value of a is: "<<obj.a<<endl;


cout << "The value of a is: "<<ptr->a<<endl; // Accessing member
with pointer
}
Output:
The value of a is: 10
The value of a is: 10

 Here you can see that we have declared a pointer of class type which points to
class's object. We can access data members and member functions using pointer
name with arrow -> symbol.
Polymorphism in C++
The word polymorphism means having many forms. In simple words, we can define
polymorphism as the ability of a message to be displayed in more than one form. A real-life
example of polymorphism, a person at the same time can have different characteristics. Like
a man at the same time is a father, a husband, an employee. So the same people possess
different behavior in different situations. This is called polymorphism. Polymorphism is
considered as one of the important features of Object Oriented Programming.

In C++ polymorphism is mainly divided into two types:

 Compile time Polymorphism


 Runtime Polymorphism
1. Compile time polymorphism:

This type of polymorphism is achieved by function overloading or operator overloading.

a. Function Overloading:
When there are multiple functions with same name but different parameters then these
functions are said to be overloaded. Functions can be overloaded by change in number of
arguments or/and change in type of arguments.

// C++ program for function overloading


#include <bits/stdc++.h>

using namespace std;


class Geeks
{
public:

// function with 1 int parameter


void func(int x)
{
cout << "value of x is " << x << endl;
}

// function with same name but 1 double parameter


void func(double x)
{
cout << "value of x is " << x << endl;
}

// function with same name and 2 int parameters


void func(int x, int y)
{
cout << "value of x and y is " << x << ", " << y << endl;
}
};

int main() {

Geeks obj1;

// Which function is called will depend on the parameters


passed
// The first 'func' is called
obj1.func(7);

// The second 'func' is called


obj1.func(9.132);

// The third 'func' is called


obj1.func(85,64);
return 0;
}

Output:
value of x is 7
value of x is 9.132
value of x and y is 85, 64

In the above example, a single function named func acts differently in three different
situations which is the property of polymorphism.

b. Operator Overloading:

C++ also provides option to overload operators. For example, we can make the operator
(‘+’) for string class to concatenate two strings. We know that this is the addition operator
whose task is to add two operands. So a single operator ‘+’ when placed between integer
operands, adds them and when placed between string operands, concatenates them.

Example:

// CPP program to illustrate


// Operator Overloading
#include<iostream>
using namespace std;

class Complex {
private:
int real, imag;
public:
Complex(int r = 0, int i =0) {real = r; imag = i;}

// This is automatically called when '+' is used with


// between two Complex objects
Complex operator + (Complex const &obj) {
Complex res;
res.real = real + obj.real;
res.imag = imag + obj.imag;
return res;
}
void print() { cout << real << " + i" << imag << endl; }
};
int main()
{
Complex c1(10, 5), c2(2, 4);
Complex c3 = c1 + c2; // An example call to "operator+"
c3.print();
}
Output:

12 + i9

In the above example the operator ‘+’ is overloaded. The operator ‘+’ is an addition operator
and can add two numbers(integers or floating point) but here the operator is made to
perform addition of two imaginary or complex numbers.

2. Runtime polymorphism:
This type of polymorphism is achieved by Function Overriding.

a. Function overriding
On the other hand occurs when a derived class has a definition for one of the member
functions of the base class. That base function is said to be overridden.

// C++ program for function overriding

#include <bits/stdc++.h>
using namespace std;

class base
{
public:
virtual void print ()
{ cout<< "print base class" <<endl; }

void show ()
{ cout<< "show base class" <<endl; }
};

class derived:public base


{
public:
void print () //print () is already virtual function in derived
class, we could also declared as virtual void print () explicitly
{ cout<< "print derived class" <<endl; }

void show ()
{ cout<< "show derived class" <<endl; }
};
//main function
int main()
{
base *bptr;
derived d;
bptr = &d;

//virtual function, binded at runtime (Runtime polymorphism)


bptr->print();

// Non-virtual function, binded at compile time


bptr->show();

return 0;
}

Output:

print derived class


show base class
Virtual Function in C++

A virtual function is a member function which is declared within a base class and is re-
defined (Overridden) by a derived class. When you refer to a derived class object using a
pointer or a reference to the base class, you can call a virtual function for that object and
execute the derived class’s version of the function.

 Virtual functions ensure that the correct function is called for an object, regardless of
the type of reference (or pointer) used for function call.
 They are mainly used to achieve Runtime polymorphism
 Functions are declared with a virtual keyword in base class.
 The resolving of function call is done at Run-time.

Rules for Virtual Functions

1. Virtual functions cannot be static.


2. A virtual function can be a friend function of another class.
3. Virtual functions should be accessed using pointer or reference of base class type to
achieve run time polymorphism.
4. The prototype of virtual functions should be the same in the base as well as derived
class.
5. They are always defined in the base class and overridden in a derived class. It is not
mandatory for the derived class to override (or re-define the virtual function), in that
case, the base class version of the function is used.
6. A class may have virtual destructor but it cannot have a virtual constructor.

Compile-time(early binding) VS run-time(late binding) behavior of Virtual Functions

Consider the following simple program showing run-time behavior of virtual functions.

// CPP program to illustrate


// concept of Virtual Functions

#include <iostream>
using namespace std;

class base {
public:
virtual void print()
{
cout << "print base class" << endl;
}

void show()
{
cout << "show base class" << endl;
}
};

class derived : public base {


public:
void print()
{
cout << "print derived class" << endl;
}

void show()
{
cout << "show derived class" << endl;
}
};

int main()
{
base* bptr;
derived d;
bptr = &d;

// virtual function, binded at runtime


bptr->print();

// Non-virtual function, binded at compile time


bptr->show();
}
Output:

print derived class


show base class

Explanation:
Runtime polymorphism is achieved only through a pointer (or reference) of base class type.
Also, a base class pointer can point to the objects of base class as well as to the objects of
derived class. In above code, base class pointer ‘bptr’ contains the address of object ‘d’ of
derived class.
Late binding (Runtime) is done in accordance with the content of pointer (i.e. location
pointed to by pointer) and Early binding(Compile time) is done according to the type of
pointer, since print() function is declared with virtual keyword so it will be bound at run-
time (output is print derived class as pointer is pointing to object of derived class ) and
show() is non-virtual so it will be bound during compile time(output is show base class as
pointer is of base type ).
NOTE: If we have created a virtual function in the base class and it is being overridden in the
derived class then we don’t need virtual keyword in the derived class, functions are
automatically considered as virtual functions in the derived class.

Working of virtual functions (concept of VTABLE and VPTR)


As discussed here, if a class contains a virtual function then compiler itself does two things:

1. If object of that class is created then a virtual pointer (VPTR) is inserted as a data
member of the class to point to VTABLE of that class. For each new object created, a
new virtual pointer is inserted as a data member of that class.
2. Irrespective of object is created or not, a static array of function pointer called
VTABLE where each cell contains the address of each virtual function contained in
that class.

Consider the example below:

// CPP program to illustrate


// working of Virtual Functions
#include <iostream>
using namespace std;

class base {
public:
void fun_1() { cout << "base-1\n"; }
virtual void fun_2() { cout << "base-2\n"; }
virtual void fun_3() { cout << "base-3\n"; }
virtual void fun_4() { cout << "base-4\n"; }
};
class derived : public base {
public:
void fun_1() { cout << "derived-1\n"; }
void fun_2() { cout << "derived-2\n"; }
void fun_4(int x) { cout << "derived-4\n"; }
};

int main()
{
base* p;
derived obj1;
p = &obj1;

// Early binding because fun1() is non-virtual


// in base
p->fun_1();

// Late binding (RTP)


p->fun_2();

// Late binding (RTP)


p->fun_3();

// Late binding (RTP)


p->fun_4();

// Early binding but this function call is


// illegal(produces error) becasue pointer
// is of base type and function is of
// derived class
// p->fun_4(5);
}
Output:

base-1
derived-2
base-3
base-4
Explanation:
Initially, we create a pointer of type base class and initialize it with the address of the
derived class object. When we create an object of the derived class, the compiler creates a
pointer as a data member of the class containing the address of VTABLE of the derived class.
Similar concept of Late and Early Binding is used as in above example. For fun_1() function
call, base class version of function is called, fun_2() is overridden in derived class so derived
class version is called, fun_3() is not overridden in derived class and is virtual function so
base class version is called, similarly fun_4() is not overridden so base class version is called.
NOTE: fun_4(int) in derived class is different from virtual function fun_4() in base class as
prototype of both the function is different.
C++ Friend Functions

A friend function of a class is defined outside that class' scope but it has the right to access
all private and protected members of the class. Even though the prototypes for friend
functions appear in the class definition, friends are not member functions.

A friend can be a function, function template, or member function, or a class or class


template, in which case the entire class and all of its members are friends.

To declare a function as a friend of a class, precede the function prototype in the class
definition with keyword friend as follows −

class Box
{
double width;

public:
double length;
friend void printWidth( Box box );
void setWidth( double wid );
};

To declare all member functions of class ClassTwo as friends of class ClassOne, place a
following declaration in the definition of class ClassOne −

friend class ClassTwo;

Consider the following program −

#include <iostream>

using namespace std;

class Box {
double width;

public:
friend void printWidth( Box box );
void setWidth( double wid );
};

// Member function definition


void Box::setWidth( double wid ) {
width = wid;
}

// Note: printWidth() is not a member function of any class.


void printWidth( Box box ) {
/* Because printWidth() is a friend of Box, it can
directly access any member of this class */
cout << "Width of box: " << box.width <<endl;
}

// Main function for the program


int main() {
Box box;

// set box width without member function


box.setWidth(10.0);

// Use friend function to print the wdith.


printWidth( box );

return 0;
}

When the above code is compiled and executed, it produces the following result −

Width of box: 10

You might also like