POLYMORPHISM
POLYMORPHISM:
The two type of polymorphism in C++ are:
A) Static Polymorphism(early binding)
B) Dynamic Polymorphism(late binding or run-time binding)
The two type of polymorphism in C++ are:
A) Static Polymorphism(early binding)
B) Dynamic Polymorphism(late binding or run-time binding)
A) Static Polymorphism:
(i) Function Overloading
(ii) Operator Overloading
(i) Function Overloading:
More than one function can have the same name but with different argument list.
void func_ABC(int a, int b);
void func_ABC(float a, float b);
void func_ABC(char a, char b);
Member functions of a class can also be overloaded.
(ii) Operator Overloading:
a) Operators can be overloaded, so that the user-defined data types can use the operators.
b) Both unary and binary operators can be overloaded.
a) Operators can be overloaded, so that the user-defined data types can use the operators.
b) Both unary and binary operators can be overloaded.
return-type operator(parameter);
Member Functions: (Operator Overloading)
a) No parameters are required for unary operators(we have this pointer).
b) One parameter is required for binary operators.
class A
{
A operator ++();
A operator +(A a);
};
A a;
a++;
Friend Functions: (Operator Overloading)
a) One parameter is required for unary operators.
b) Two parameters are required for binary operators.
class A
{
friend A operator ++(A a);
friend A operator +(A x, A y);
};
A a, b, c;
c = a + b;
a) One parameter is required for unary operators.
b) Two parameters are required for binary operators.
class A
{
friend A operator ++(A a);
friend A operator +(A x, A y);
};
A a, b, c;
c = a + b;
Example:
Operator Overloading: new, delete, + operator.
#include <iostream>
using namespace std;
class Base
{
int i;
float f;
public:
Base()
{
cout << "Default Constructor" << endl;
i = 0;
f = 0.0;
}
Base(int i, float f)
{
cout << "Parameterized Constructor" << endl;
this->i = i;
this->f = f;
}
Base(const Base& b)
{
cout << "Copy Constructor" << endl;
this->i = b.i;
this->f = b.f;
}
void operator=(const Base& obj)
{
cout << "Asignment Operator" << endl;
this->i = obj.i;
this->f = obj.f;
}
void* operator new(size_t s)
{
cout << "new overloading" << endl;
return malloc(s);
}
void operator delete(void* obj)
{
cout << "delete overloading" << endl;
free(obj);
}
/*
Base operator+(const Base obj)
{
cout<<"operator + overloading - member function"<<endl;
Base res;
res.i = this->i + obj.i;
res.f = this->f + obj.f;
return res;
}
*/
friend Base operator+(Base obj1, Base obj2)
{
cout<<"operator + overloading - friend function"<<endl;
Base obj;
obj.i = obj1.i + obj2.i;
obj.f = obj1.f + obj2.f;
return obj;
}
void Display()
{
cout << "i = " << i << endl;
cout << "f = " << f << endl;
}
};
int main()
{
Base b;
Base c(10, 20);
Base d(c);
b.Display();
c.Display();
d.Display();
Base b1(1, 2);
Base b2(10, 20);
Base b3 = b1 + b2;
b1.Display();
b2.Display();
b3.Display();
Base* pObj = new Base();
Base* pObj1 = new Base(100, 200);
Base* pObj2 = new Base(*pObj1);
pObj->Display();
pObj1->Display();
pObj2->Display();
delete pObj;
delete pObj1;
delete pObj2;
return 0;
}
B) Dynamic Polymorphism:
(i) virtual keyword is used to attain dynamic polymorphism.
(ii) vtable is created for the base class, which has virtual functions, and for its derived classes.
(iii) When we create an object for these classes, a vptr is included by the compiler. The vptr points to the corresponding vtable.
class A
{
public:
virtual void func_A();
virtual void func_B();
};
class B : public A
{
public:
virtual void func_A();
};
A *a = new A(); //vtable of A
B *b = new B(); //vtable of B
A *c = new B(); //vtable of B
Abstract Classes and Pure virtual functions:
a) If we declare a pure virtual function in a base class, all the derived classes must implement the function in their class.
b) The function which has a pure virtual function becomes an abstract class.
c) We cannot instantiate the abstract class.
d) The base class pointer can be assigned to a derived class object.
b) The function which has a pure virtual function becomes an abstract class.
c) We cannot instantiate the abstract class.
d) The base class pointer can be assigned to a derived class object.
VIRTUAL DESTRUCTOR:
A virtual destructor in C++ is a destructor declared in a base class with the virtual keyword.Its primary purpose is to ensure that the correct destructor is called for a derived class
object when it is deleted through a pointer to its base class.
Example:
#include <iostream>
using namespace std;
class Base
{
int i;
public:
Base()
{
cout << "Base - Default Constructor" << endl;
i = 0;
}
Base(int i)
{
cout << "Base - Parameterized Constructor" << endl;
this->i = i;
}
virtual ~Base()
{
cout << "Base Destructor" << endl;
}
void Display()
{
cout << "i = " << i << endl;
}
};
class Derived : public Base
{
int d;
public:
Derived()
{
cout << "Derived - Default Constructor" << endl;
d = 0;
}
Derived(int d)
{
cout << "Derived - Parameterized Constructor" << endl;
this->d = d;
}
~Derived()
{
cout << "Destructor of Derived" << endl;
}
void Display()
{
cout << "d = " << d << endl;
}
};
int main()
{
cout << "Base Object" << endl;
Base* obj = new Base(1000);
obj->Display();
cout << endl;
cout << "Derived Object" << endl;
Derived* dObj = new Derived(100);
dObj->Display();
cout << endl;
cout << "Base - Derived Object" << endl;
Base* bObj = new Derived(10);
bObj->Display();
cout << endl;
cout << "Destructor" << endl;
delete obj;
delete dObj;
delete bObj;
return 0;
}