Index
Introduction
Polymorphism in Object Oriented programming means “many forms.” It allows one function, method, or operator to behave differently based on the object or data it’s working with.
In C++, there are two types of polymorphism:
Compile-Time Polymorphism (Static Binding)
Compile-time polymorphism, also known as static binding or early binding, happens when the method or function to be executed is determined during compilation. It is typically achieved through:
Function Overloading:
Multiple functions with the same name but different parameter types.
For example
#include <iostream>
using namespace std;
class Calculator {
public:
// Function to add two integers
int add(int a, int b) {
return a + b;
}
// Function to add two double values
double add(double a, double b) {
return a + b;
}
// Function to add three integers
int add(int a, int b, int c) {
return a + b + c;
}
};
int main() {
Calculator calc;
cout << "Sum of two integers: " << calc.add(10, 20) << endl; // Calls int version
cout << "Sum of two doubles: " << calc.add(5.5, 10.5) << endl; // Calls double version
cout << "Sum of three integers: " << calc.add(1, 2, 3) << endl; // Calls three-argument version
return 0;
}
Output:
Sum of two integers: 30
Sum of two doubles: 16
Sum of three integers: 6
Explanation:
Step 1: Class Declaration:
class Calculator {
public:
// Function declarations go here
};
- The
Calculator
class contains three overloadedadd()
functions that handle different numbers and types of arguments.
Step 2: First add()
Function: Add Two Integers:
int add(int a, int b) {
return a + b;
}
- This function takes two integers as input and returns their sum.
- Example call:
calc.add(10, 20);
calls this version of the function because both arguments are integers.
Step 3: Second add()
Function: Add Two Double Values:
double add(double a, double b) {
return a + b;
}
- This function takes two double values as input and returns their sum.
- Example call:
calc.add(5.5, 10.5);
calls this version of the function because both arguments are of typedouble
Step 4: Third add()
Function: Add Three Integers:
int add(int a, int b, int c) {
return a + b + c;
}
- This function takes three integers as input and returns their sum.
- Example call:
calc.add(1, 2, 3);
calls this version of the function because it has three integer arguments.
Step 5: Main Function:
int main() {
Calculator calc;
cout << "Sum of two integers: " << calc.add(10, 20) << endl; // Calls int version
cout << "Sum of two doubles: " << calc.add(5.5, 10.5) << endl; // Calls double version
cout << "Sum of three integers: " << calc.add(1, 2, 3) << endl; // Calls three-argument version
return 0;
}
- In the
main()
function, an objectcalc
of classCalculator
is created. - We call the
add()
function three times with different arguments:calc.add(10, 20)
calls the first version (with two integers).calc.add(5.5, 10.5)
calls the second version (with two doubles).calc.add(1, 2, 3)
calls the third version (with three integers).
Operator Overloading:
Operator overloading is a feature in Object-Oriented Programming (OOP) that allows you to define how operators like +
, -
, *
, and ==
behave when applied to user-defined data types (like objects of a class). The same operator behaves differently based on the types of operands.
For example:
#include <iostream>
using namespace std;
class Point {
private:
int x, y;
public:
// Constructor to initialize the point
Point(int a = 0, int b = 0) : x(a), y(b) {}
// Overloading the + operator
Point operator + (const Point& p) {
Point temp;
temp.x = x + p.x;
temp.y = y + p.y;
return temp;
}
// Function to display the point
void display() {
cout << "(" << x << ", " << y << ")" << endl;
}
};
int main() {
Point p1(2, 3); // Point (2, 3)
Point p2(4, 5); // Point (4, 5)
Point p3 = p1 + p2; // Adding two points using overloaded + operator
cout << "Point 1: "; p1.display();
cout << "Point 2: "; p2.display();
cout << "Sum of Points: "; p3.display(); // Displays (6, 8)
return 0;
}
Output:
Point 1: (2, 3)
Point 2: (4, 5)
Sum of Points: (6, 8)
Explanation:
- Class
Point
: Represents a point in a 2D coordinate system withx
andy
coordinates. - Constructor: Initializes the
x
andy
coordinates of the point. For example,Point(2, 3)
creates a point at coordinates (2, 3). - Operator Overloading Function (
operator +
):- This function is used to overload the
+
operator so it can add twoPoint
objects. - Inside the function, the
x
andy
values of the two points are added together, and the result is stored in a temporary objecttemp
, which is then returned.
- This function is used to overload the
- Display Function: Displays the point in the form
(x, y)
.
4. In main()
:
p1 + p2
: This calls the overloaded+
operator function. It adds thex
andy
values ofp1
andp2
and returns a newPoint
object with the result (6, 8).- The sum of points is displayed as
(6, 8)
.
Run-Time Polymorphism(Dynamic Binding)
Run-time polymorphism (also known as dynamic polymorphism) is a feature in Object-Oriented Programming (OOP) that allows a program to decide which method to execute at runtime based on the type of object that is invoking the method. It is typically achieved using inheritance and virtual functions.
Virtual Function
Virtual functions are a key feature in Object-Oriented Programming (OOP) that enable run-time polymorphism. They allow derived classes to override functions defined in a base class, and the correct function implementation is selected at runtime based on the actual object type.
For example:
#include <iostream>
using namespace std;
// Base class
class Shape {
public:
// Virtual function to draw the shape
virtual void draw() {
cout << "Drawing a Shape" << endl;
}
};
// Derived class
class Circle : public Shape {
public:
// Override the draw function
void draw() override {
cout << "Drawing a Circle" << endl;
}
};
// Another derived class
class Rectangle : public Shape {
public:
// Override the draw function
void draw() override {
cout << "Drawing a Rectangle" << endl;
}
};
int main() {
Shape* shapePtr; // Base class pointer
Circle circle; // Derived class object
Rectangle rectangle; // Another derived class object
shapePtr = &circle; // Base class pointer points to Circle object
shapePtr->draw(); // Calls Circle's draw() method
shapePtr = &rectangle; // Base class pointer points to Rectangle object
shapePtr->draw(); // Calls Rectangle's draw() method
return 0;
}
Output:
Drawing a Circle
Drawing a Rectangle
Explanation:
Step 1: Base Class Shape
:
- Contains a virtual function
draw()
, which is intended to be overridden by derived classes.
class Shape {
public:
virtual void draw() {
cout << "Drawing a Shape" << endl;
}
};
Step 2: Derived Class Circle
:
- Inherits from
Shape
and overrides thedraw()
function.
class Circle : public Shape {
public:
void draw() override {
cout << "Drawing a Circle" << endl;
}
};
Step 3: Derived Class Rectangle
:
- Inherits from
Shape
and also overrides thedraw()
function.
class Rectangle : public Shape {
public:
void draw() override {
cout << "Drawing a Rectangle" << endl;
}
};
Step 4: Main Function:
- Creates a base class pointer
shapePtr
and assigns it the address ofCircle
andRectangle
objects one at a time. - When
shapePtr->draw()
is called, the appropriatedraw()
function is invoked based on the actual object type (Circle
orRectangle
), even thoughshapePtr
is a pointer toShape
.
int main() {
Shape* shapePtr; // Base class pointer
Circle circle; // Derived class object
Rectangle rectangle; // Another derived class object
shapePtr = &circle; // Base class pointer points to Circle object
shapePtr->draw(); // Calls Circle's draw() method
shapePtr = &rectangle; // Base class pointer points to Rectangle object
shapePtr->draw(); // Calls Rectangle's draw() method
return 0;
}
Summary:
- Virtual Function: Declared in the base class using the
virtual
keyword, allowing derived classes to provide their own implementations. - Run-Time Polymorphism: The actual function called is determined at runtime based on the type of the object pointed to by the base class pointer.
- Overriding: Derived classes override the virtual function to provide specific behavior.