What is Polymorphism in C++

What is Polymorphism in C++

7 mins read414 Views Comment
Updated on Apr 26, 2023 10:01 IST

Discover the power of polymorphism in C++ with our comprehensive guide. Learn how to use virtual functions, inheritance, and templates to create flexible and reusable code. Whether you’re a beginner or an experienced programmer, our article will teach you how to take advantage of one of the most important concepts in object-oriented programming.

2023_04_Feature-Image-Templates-9.jpg

Polymorphism in C++ is the ability of an object to take on multiple forms. It is a fundamental concept in object-oriented programming (OOP) and allows objects of different classes to be treated as if they were objects of the same class. 

Polymorphism is a powerful concept in C++ that allows for code reuse, flexibility, and extensibility. It is an essential tool for creating well-designed and maintainable object-oriented programs.

Types of Polymorphism in C++

There are two main types of polymorphism in C++: 

  1. Compile-time Polymorphism 
  2. Run-time Polymorphism

Compile-time polymorphism, also known as static polymorphism, is achieved through function overloading and templates. Function overloading is the process of defining multiple functions with the same name but with different parameters. When a function is called, the compiler determines which version of the function to use based on the arguments passed to it. Templates are another way to achieve compile-time polymorphism, where a function or class can be parameterized with one or more types or values.

Run-time polymorphism, also known as dynamic polymorphism, is achieved through inheritance and virtual functions. Inheritance is the process of creating a new class from an existing class, which inherits all the data members and member functions of the base class. Virtual functions are functions that are declared in the base class and are overridden in the derived classes. The correct version of a virtual function is chosen at run-time based on the actual object that the pointer or reference points to when a virtual function is invoked using a pointer or reference to the base class.

Now let’s take a deeper look at each type of polymorphism in C++.

Compile-Time Polymorphism

When a program is being compiled, a function is invoked as part of compile-time polymorphism.

Function Overloading

Function overloading in C++ is the process of defining multiple functions with the same name but with different parameters. The compiler decides which version to use based on the inputs supplied to the function. This makes it possible to construct functions with more freedom and makes it simpler to write code that is easier to read and maintain.

Here is an example of function overloading in C++:

 
#include <iostream>
using namespace std;
// Function to calculate the area of a rectangle
int area(int length, int width) {
return length * width;
}
// Function to calculate the area of a circle
double area(double radius) {
return 3.14 * radius * radius;
}
int main() {
int length = 5;
int width = 3;
double radius = 2.5;
// Call the area function with integer arguments
int rectArea = area(length, width);
cout << "The area of the rectangle is: " << rectArea << endl;
// Call the area function with double argument
double circleArea = area(radius);
cout << "The area of the circle is: " << circleArea << endl;
return 0;
}
Copy code

Output:

The area of the rectangle is: 15

The area of the circle is: 19.625

As you can see, the program correctly calculates the areas of the rectangle and circle using the appropriate version of the area function based on the arguments passed to it.

In the above code, we have defined two functions with the same name area, but with different parameters. The first area function takes two integer arguments, representing the length and width of a rectangle, and returns the area of the rectangle. The second area function takes a double argument, representing the radius of a circle, and returns the area of the circle.

In the main function, we first declare the necessary variables and then call the area function twice. The first call to area passes two integers representing the length and width of a rectangle, and the second call to area passes a double representing the radius of a circle.

Operator Overloading

Operator overloading in C++ allows operators such as +*, and to be used with user-defined data types. This makes it possible to create more intuitive and readable code, especially when working with complex data structures.

Here is an example of operator overloading in C++ that demonstrates how to overload the + operator to add two objects of a user-defined class:

 
#include <iostream>
using namespace std;
class Point {
private:
int x, y;
public:
// Constructor to initialize the x and y coordinates
Point(int x = 0, int y = 0) {
this->x = x;
this->y = y;
}
// Overload the + operator to add two Point objects
Point operator+(const Point& p) {
Point sum;
sum.x = x + p.x;
sum.y = y + p.y;
return sum;
}
// Overload the << operator to output the Point object in the format "(x, y)"
friend ostream& operator<<(ostream& os, const Point& p) {
os << "(" << p.x << ", " << p.y << ")";
return os;
}
};
int main() {
Point p1(1, 2);
Point p2(3, 4);
// Add two Point objects using the + operator
Point p3 = p1 + p2;
// Output the result
cout << p1 << " + " << p2 << " = " << p3 << endl;
return 0;
}
Copy code

Output

(1, 2) + (3, 4) = (4, 6)

In this example, we have created a Point class with x and y coordinates. We have overloaded the + operator to add two Point objects by creating a new Point object whose x and coordinates are the sum of the x and y coordinates of the two operands.

We have also overloaded the << operator to output the Point object in the format (x, y).

In the main() function, we have created two Point objects p1 and p2, and we have used the overloaded + operator to add them together to get a new Point object p3. Finally, we have output the result in the format (x1, y1) + (x2, y2) = (x3, y3).

Run-time Polymorphism

When a program is executed, a function is invoked as part of run-time polymorphism. Run-time polymorphism allows objects of different classes to be treated as objects of the same base class during run-time.

Function Overriding

Function overriding is a feature in C++ that allows a derived class to provide its own implementation of a member function that is already defined in its base class. The overridden function in the derived class needs to have exactly the same parameters, return type, and name as the function in the base class. This is known as having the same signature.

Here’s an example to illustrate function overriding in C++:

 
#include <iostream>
using namespace std;
class Animal {
public:
void makeSound() {
cout << "The animal makes a sound" << endl;
}
};
class Dog : public Animal {
public:
void makeSound() {
cout << "The dog barks" << endl;
}
};
int main() {
// create an Animal object and call its makeSound() function
Animal *animal1 = new Animal();
animal1->makeSound();
// create a Dog object and call its makeSound() function
Animal *animal2 = new Dog();
animal2->makeSound();
// free memory allocated for objects
delete animal1;
delete animal2;
return 0;
}
Copy code

Output:

The animal makes a sound

The dog barks

The output demonstrates that the makeSound() function of the Animal class is called when an Animal object is created and that the makeSound() function of the Dog class is called when a Dog object is created. This behavior is due to function overriding, which allows a derived class to implement a member function already defined in its base class.

Virtual Functions

Virtual functions are a feature in C++ that allows a function in a base class to be overridden in a derived class. They are declared in the base class using the virtual keyword and overridden in the derived class using the override keyword.

When a virtual function is called on an object, the function call is resolved at run-time based on the type of the object. This means that if the object is of the derived class, the overridden function in the derived class is called; otherwise, the function in the base class is called.

Here’s an example to illustrate virtual functions in C++:

 
#include <iostream>
using namespace std;
class Animal {
public:
virtual void makeSound() {
cout << "The animal makes a sound" << endl;
}
};
class Dog : public Animal {
public:
void makeSound() override {
cout << "The dog barks" << endl;
}
};
int main() {
// create an Animal object and call its makeSound() function
Animal *animal1 = new Animal();
animal1->makeSound();
// create a Dog object and call its makeSound() function
Animal *animal2 = new Dog();
animal2->makeSound();
// free memory allocated for objects
delete animal1;
delete animal2;
return 0;
}
Copy code

Output:

The animal makes a sound

The dog barks

In this example, the Animal class has a virtual function makeSound(), which is overridden in the Dog class. In the main() function, we create an object of type Animal and an object of type Dog and call the makeSound() function on each. At run-time, the correct implementation of the makeSound() function is called based on the type of the object.

Run-time Vs Compile-time Polymorphism

Here’s a table that highlights the key differences between run-time polymorphism (using virtual functions) and compile-time polymorphism (using function overloading and templates) in C++:

Run-time Polymorphism Compile-time Polymorphism
Mechanism Virtual functions Function overloading, templates
Execution Determined at runtime based on object type Determined at compile-time based on function signature or template argument type
Function signature Same function name, same parameter list, different implementation in derived classes Same function name, different parameter list, the same implementation
Overhead Additional runtime overhead due to dynamic dispatch No additional runtime overhead
Flexibility Allows for dynamic binding and flexibility in object-oriented programming Limited to fixed number of overloaded functions or template argument types
Use cases Polymorphic behavior, hierarchical modeling of objects Functionality reuse, performance optimization

Conclusion

 In this article we have managed to cover the following concepts associated with Polymorphism in C++:

  • What is polymorphism in C++?
  • Types of Polymorphism in C++
  • Compile-Time polymorphism
  • Run-Time Polymorphism
  • Difference between Run-time vs Compile-time polymorphism

FAQs

What is polymorphism in C++, and how does it work?

Polymorphism is a concept in object-oriented programming where an object can take on different forms or behaviors. In C++, it can be achieved through virtual functions, inheritance, and templates.

How is inheritance used to achieve polymorphism in C++?

Inheritance allows a derived class to inherit properties and behavior from a base class. By using virtual functions in the base class, a derived class can override those functions to implement its own behavior, achieving polymorphism.

What is a virtual function in C++, and how is it used to achieve polymorphism?

A virtual function is a function in a base class that is marked as "virtual" and can be overridden by a derived class. This allows objects of different derived classes to be treated as objects of the base class, enabling polymorphism.

How does function overloading relate to polymorphism in C++?

Function overloading allows for multiple functions with the same name but different parameters to be defined in a class. This allows for polymorphism because the correct function will be called based on the parameters passed to it.

What are the advantages of using polymorphism in C++?

Polymorphism allows for code to be more flexible, modular, and reusable. It also enables easier maintenance and modification of code.

About the Author

This is a collection of insightful articles from domain experts in the fields of Cloud Computing, DevOps, AWS, Data Science, Machine Learning, AI, and Natural Language Processing. The range of topics caters to upski... Read Full Bio