0% found this document useful (0 votes)
38 views49 pages

Unit 4

Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
38 views49 pages

Unit 4

Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
You are on page 1/ 49

VIRTUAL FUNCTIONS

• A virtual function is a member function which is declared within


base class and is re-defined (Overriden) in 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.

1
VIRTUAL FUNCTIONS

• The compiler binds virtual function at runtime,


hence called runtime polymorphism.
• Use of virtual function allows the program to decide
at runtime which function is to be called based on
the type of the object pointed by the pointer.
• In C++, the member function of a class is selected at
runtime using virtual function.
• The function in the base class is overridden by the
function with the same name of the derived class.

2
VIRTUAL FUNCTIONS
Class class_name
{
public:
virtual returntype func_name( args.. )
{
//function definition
}
}

3
VIRTUAL FUNCTIONS
Rules for Virtual Functions
• They must be declared in public section of class.
• Virtual functions cannot be static and also cannot be a friend
function of another class.
• Virtual functions should be accessed using pointer or reference of
base class type to achieve run time polymorphism.
• The prototype of virtual functions should be same in base as well as
derived class.
• They are always defined in base class and overridden in derived class.
It is not mandatory for derived class to override (or re-define the
virtual function), in that case base class version of function is used.
• A class may have virtual destructor but it cannot have a virtual
constructor.
4
Example: Without using virtual keyword
#include <iostream>
using namespace std;
class A
{
int x=5;
public:
void display()
{
std::cout << "Value of x is : " << x<<std::endl;
}
};
class B: public A
{
int y = 10;
public:
void display()
{
std::cout << "Value of y is : " <<y<< std::endl;
}
};
int main() Output:
{ Value of x:5
A *a;
B b;
a = &b;
a->display();
return 0;
}
Example: With using virtual keyword
#include <iostream>
using namespace std;
class A
{
int x=5;
public:
virtual void display()
{
std::cout << "Value of x is : " << x<<std::endl;
}
};
class B: public A
{
int y = 10;
public:
void display()
{
std::cout << "Value of y is : " <<y<< std::endl;
}
};
int main() Output:
{ Value of y is:10
A *a;
B b;
a = &b;
a->display();
return 0;
}
NEED OF VIRTUAL FUNCTION
• The pointer can only access the base class members but not
the members of the derived class.
• Although C++ permits the base pointer to point to any object
derived from the base class, it cannot directly access the
members of the derived class.
• Therefore, there is a need for virtual function which allows the
base pointer to access the members of the derived class.
• Virtual functions allow us to create a list of base class pointers
and call methods of any of the derived classes without even
knowing kind of derived class object.

9
Pointer to Derived class objects:
• Pointers can be used to point to the base class
objects and objects of derived class.
• Pointers to objects of base class are compatible
with pointers to objects of a derived class.
• Single pointer variable can be made to point
objects belonging to different classes.
• If B is base and D is derived class then pointer
declared as a pointer to B can also be a pointer to
D.
Example:

B *cptr; // pointer to base class


B b; //Base object
D d; // Derived object
cptr=&b; //cptr store address of object b of base
class
cptr=&d; //cptr store address of object d of derived
class
Note:
• It's not possible to access the public members of
the derived class D by using cptr.
• Using base class pointer to object cptr, only those
members inherited from B can be accessed and
not the members that originally belong to D.
• For a member of D has the same name as any of
the member of B, then reference to that member
by cptr will always access the base class member.
• While C++ allows a base pointer to point to any
object derived from that base, the pointer cannot
be directly used to access all the members of the
derived class.
Example:
#include<iostream.h>
#include<conio.h>
class base
{
int a;
public:
void get()
{
cout<<"\nEnter a value for A";
cin>>a;
}
void put()
{
cout<<"\nThe Value for A "<<a;
}
};
class derived : public base
{
int a;
public:
void get()
{
cout<<"\nEnter a value for A";
cin>>a;
}
void put()
{
cout<<"\nThe Value for A "<<a;
}
};
void main()
{
base *bptr;
base b;
derived d;
cout<<"\nPointing to the base class ";
bptr=&b;
bptr->get();
bptr->put();
cout<<"\nPointing to the derived class ";
bptr=&d;
bptr->get();
bptr->put();
getch();
}
C++ Abstract class and Pure virtual Function
• A pure virtual function is a virtual function in C++ for which we
need not write any function definition and only we have to
declare it.
• And also it should be definitely derived in derived class.
• It is declared by assigning 0 in the declaration.
An abstract class is a class in C++ which have at least one pure
virtual function.
• Abstract class can have normal functions and variables along
with a pure virtual function.
• Abstract class cannot be instantiated, but pointers and
references of Abstract class type can be created.
• If an Abstract Class has derived class, they must implement all
pure virtual functions, or else they will become Abstract too.

16
Example:
#include <iostream>
using namespace std;
class Shape
{
protected:
float dimension;
public:
void getDimension()
{
cin >> dimension;
}
virtual float calculateArea() =0;
};
class Square: public Shape
{
public:
float calculateArea()
{
return dimension * dimension;
} };
class Circle : public Shape
{
public:
float calculateArea()
{
return 3.14 * dimension * dimension;
} };
int main()
{
Square square;
Circle circle;
cout << "Enter the length of the square: ";
square.getDimension();
cout << "Area of square: " << square.calculateArea() << endl;
cout << "\nEnter radius of the circle: ";
circle.getDimension();
cout << "Area of circle: " << circle.calculateArea() << endl;
return 0; }
Example:
#include<iostream>
using namespace std;
class B
{
public:
virtual void s() = 0;
};
class D:public B
{
public:
void s()
{
cout << "Virtual Function in Derived class\n";
} };
int main()
{
B *b;
D dobj;
b = &dobj;
b->s();
}

Output
Virtual Function in Derived class
Notes:
1. A class is abstract if it has at least one pure
virtual function.
2. We can have pointers and references of abstract
class type.
3. If we do not override the pure virtual function in
derived class, then derived class also becomes
abstract class.
4. An abstract class can have constructors.
Virtual Destructors in C++
• A virtual destructor is used to free up the
memory space allocated by the derived class
object or instance while deleting instances of
the derived class using a base class pointer
object.
• A base or parent class destructor use
the virtual keyword that ensures both base
class and the derived class destructor will be
called at run time, but it called the derived class
first and then base class to release the space
occupied by both destructors.
23
Why we use virtual destructor in C++?

• When an object in the class goes out of scope or the execution of the main()
function is about to end, a destructor is automatically called into the program
to free up the space occupied by the class' destructor function.

• When a pointer object of the base class is deleted that points to the derived
class, only the parent class destructor is called due to the early bind by the
compiler.

• In this way, it skips calling the derived class' destructor, which leads to memory
leaks issue in the program.

• And when we use virtual keyword preceded by the destructor tilde (~) sign
inside the base class, it guarantees that first the derived class' destructor is
called.

• Then the base class' destructor is called to release the space occupied by both
destructors in the inheritance class.
24
Example: without using virtual keyword
#include<iostream>
using namespace std;
class Base
{
public:
Base()
{
cout<<"\nConstructor Base class";
}
~Base()
{
cout<<"\nDestructor Base class";
}
};
class Derived:public Base
{
public:
Derived()
{
cout<<"\nConstructor Derived class";
}
~Derived()
{
cout<<"\nDestructor Derived class";
}
};
int main()
{
Base *bptr=new Derived;
delete bptr;
}
Example: With using virtual keyword
#include<iostream>
using namespace std;
class Base
{
public:
Base()
{
cout<<"\nConstructor Base class";
}
virtual ~Base()
{
cout<<"\n Destructor Base class";
}
};
class Derived:public Base
{
public:
Derived()
{
cout<<"\nConstructor Derived class";
}
~Derived()
{
cout<<"\nDestructor Derived class";
}
};
int main()
{
Base *bptr=new Derived;
delete bptr;
}
Note:
• If the base class destructor does not use a
virtual keyword, only the base class destructor
will be called or deleted its occupied space
because the pointer object is pointing to the
base class.
• So it does not call the derived class destructor to
free the memory used by the derived class,
which leads to memory leak for the derived
class.
Pure Virtual Destructors in C++

• Pure Virtual Destructors are legal in C++. Also,


pure virtual Destructors must be defined,
which is against the pure virtual behaviour.
• The only difference between Virtual and Pure
Virtual Destructor is, that pure virtual
destructor will make its Base class Abstract,
hence you cannot create object of that class.
• There is no requirement of implementing pure
virtual destructors in the derived classes.
30
Why do we need a pure virtual destructor in C++?

• There are no ill-effects of allowing a pure virtual


destructor in C++ program.
• It is must to provide a function body for pure virtual
destructor as derived class’s destructor is called
first before the base class destructor, so if we do
not provide a function body, it will find out nothing
to be called during object destruction and error will
occur.
• We can make easily an abstract class by making a
pure virtual destructor with its definition.
31
Example:
class Base
{
public:
virtual ~Base() = 0; // Pure Virtual Destructor
};
// Definition of Pure Virtual Destructor
Base::~Base()
{
cout << "Base Destructor\n";
}
class Derived:public Base
{
public: ~Derived()
{
cout<< "Derived Destructor";
} };
Binding
• Binding refers to the process of converting
identifiers (such as variable and performance
names) into addresses.
• Binding is done for each variable and
functions.
• For functions, it means that matching the call
with the right function definition by the
compiler. It takes place either at compile time
or at runtime.
33
Binding

34
Binding
• Early Binding (compile-time polymorphism) : As the
name indicates, compiler (or linker) directly associate
an address to the function call. It replaces the call
with a machine language instruction that tells the
mainframe to leap to the address of the function.
• Late Binding (Run time polymorphism) : In this, the
compiler adds code that identifies the kind of object
at runtime then matches the call with the right
function definition. This can be achieved by declaring
a virtual function.

35
Generic Programming with Templates
• Templates are powerful features of C++ which
allows you to write generic programs.
• In simple terms, you can create a single function or
a class to work with different data types using
templates.
• Templates are often used in larger codebase for the
purpose of code reusability and flexibility of the
programs.
• The concept of templates can be used in two
different ways:
– Function Templates
– Class Templates
Function Templates:
• A function template works in a similar to a
normal function, with one key difference.
• A single function template can work with different
data types at once but, a single normal function
can only work with one set of data types.
• Normally, if you need to perform identical
operations on two or more types of data, you use
function overloading to create two functions with
the required function declaration.
• However, a better approach would be to use
function templates because you can perform the
same task writing less and maintainable code.
How to declare a function template?
• A function template starts with the
keyword template followed by template
parameter/s inside < > which is followed by
function declaration.
template <class T>
T someFunction(T arg)
{
//function block
}
• In the above code, T is a template argument that
accepts different data types (int, float),
and class is a keyword.
• You can also use keyword typename instead of
class in the above example.
• When, an argument of a data type is passed
to someFunction( ), compiler generates a new
version of someFunction() for the given data type.
Example 1: Function Template to find the largest number
#include <iostream>
using namespace std;
<class T>
T Large(T n1, T n2)
{
return (n1 > n2) ? n1 : n2;
}
int main()
{
int i1, i2;
float f1, f2;
char c1, c2;
cout << "Enter two integers:\n";
cin >> i1 >> i2;
cout << Large(i1, i2) <<" is larger." << endl;
cout << "\nEnter two floating-point numbers:\n";
cin >> f1 >> f2;
cout << Large(f1, f2) <<" is larger." << endl;
cout << "\nEnter two characters:\n";
cin >> c1 >> c2;
cout << Large(c1, c2) << " has larger ASCII value.";
return 0;
}
Example 2: Swap Data Using Function Templates
#include <iostream>
using namespace std;
template <typename T>
void Swap(T &n1, T &n2)
{
T temp;
temp = n1;
n1 = n2;
n2 = temp;
}
int main()
{
int i1 = 1, i2 = 2;
float f1 = 1.1, f2 = 2.2;
char c1 = 'a', c2 = 'b';
cout << "Before passing data to function template.\n";
cout << "i1 = " << i1 << "\ni2 = " << i2;
cout << "\nf1 = " << f1 << "\nf2 = " << f2;
cout << "\nc1 = " << c1 << "\nc2 = " << c2;
Swap(i1, i2);
Swap(f1, f2);
Swap(c1, c2);
cout << "\n\nAfter passing data to function template.\n";
cout << "i1 = " << i1 << "\ni2 = " << i2;
cout << "\nf1 = " << f1 << "\nf2 = " << f2;
cout << "\nc1 = " << c1 << "\nc2 = " << c2;
return 0;
}
Class Template:
• Like function templates, you can also create class templates for generic class
operations.
• Sometimes, you need a class implementation that is same for all classes, only
the data types used are different.
• Normally, you would need to create a different class for each data type OR
create different member variables and functions within a single class.
• This will unnecessarily bloat your code base and will be hard to maintain, as a
change is one class/function should be performed on all classes/functions.
• However, class templates make it easy to reuse the same code for all data types.
How to declare a class template?
template <class T>
class className
{
... .. ...
public:
T var;
T someOperation(T arg);
... .. ...
};
• In the above declaration, T is the template argument which is a placeholder for
the data type used.
• Inside the class body, a member variable var and a member
function someOperation() are both of type T.
How to create a class template object?
• To create a class template object, you need to define the data type inside a <
> when creation.
className<dataType> classObject;
• For example:
className<int> classObject;
className<float> classObject;
className<string> classObject;
Example 3: Simple calculator using Class template
#include <iostream>
using namespace std;
template <class T>
class Calculator
{
private:
T num1, num2;
public:
Calculator(T n1, T n2)
{
num1 = n1;
num2 = n2;
}
void displayResult()
{
cout << "Numbers are: " << num1 << " and " << num2 << "." << endl;
cout << "Addition is: " << add() << endl;
cout << "Subtraction is: " << subtract() << endl;
cout << "Product is: " << multiply() << endl;
cout << "Division is: " << divide() << endl;
}
T add()
{
return num1 + num2;
}
T subtract()
{
return num1 - num2;
}
T multiply()
{
return num1 * num2;
}
T divide()
{
return num1 / num2;
} };
int main()
{
Calculator<int> intCalc(2, 1);
Calculator<float> floatCalc(2.4, 1.2);
cout << "Int results:" << endl;
intCalc.displayResult();
cout << endl << "Float results:" << endl;
floatCalc.displayResult();
return 0;
}

You might also like