Download Polymorphism in C++ and more Study notes Object Oriented Programming in PDF only on Docsity!
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.
Real life example of polymorphism, a person at the same time can have different
characteristic. Like a man at the same time is a father, a husband, an employee. So the same
person posses 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.
- 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.
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.
- Operator Overloading : C++ also provide 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 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) {
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(Overriden) 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 and also cannot be a friend function of another class.
2. Virtual functions should be accessed using pointer or reference of base class type to
achieve run time polymorphism.
3. The prototype of virtual functions should be same in base as well as derived class.
4. 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.
5. 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 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.
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.
A pure virtual function (or abstract function) in C++ is a virtual function for which we don’t
have implementation, we only declare it. A pure virtual function is declared by assigning 0 in
declaration. See the following example.
// An abstract class class Test { // Data members of class public: // Pure Virtual Function virtual void show() = 0; /* Other members */ };
A complete example:
A pure virtual function is implemented by classes which are derived from a Abstract class.
Following is a simple example to demonstrate the same.
#include using namespace std; class Base { int x; public: virtual void fun() = 0; int getX() { return x; } }; // This class inherits from Base and implements fun() class Derived: public Base { int y; public: void fun() { cout << "fun() called"; } }; int main(void) { Derived d; d.fun(); return 0; }
Output:
fun() called