Difference between Method/Function Overloading and Overriding (Polymorphism) in C++

Difference between Method/Function Overloading and Overriding (Polymorphism) in C++

Polymorphism is one of the most powerful and essential concepts of Object-Oriented Programming (OOP). It refers to the ability of a single function, method, or object to behave in different ways depending on the context in which it is used.

The term “Polymorphism” is derived from the Greek words poly (many) and morphe (forms), meaning “many forms.” Polymorphism allows you to write flexible, reusable, and maintainable code by enabling a single function or method to process different types of objects.

Types of Polymorphism in C++

C++ supports two main types of polymorphism:

  1. Compile-Time Polymorphism (Static Binding)
    • Achieved through Function Overloading or Operator Overloading.
    • The compiler decides which function or method to call during compile time.
  2. Run-Time Polymorphism (Dynamic Binding)
    • Achieved through Function Overriding.
    • The decision about which method to invoke is made at runtime, depending on the object’s actual type.

1. Compile-Time Polymorphism (Function Overloading)

In function overloading, multiple functions in the same scope have the same name but differ in the number or types of their parameters. The compiler determines the appropriate function to call based on the arguments passed.

Example: Function Overloading

#include <iostream>
#include <string>
using namespace std;

class Calculator {
public:
// Add two integers
int add(int a, int b) {
return a + b;
}

// Add three integers
int add(int a, int b, int c) {
return a + b + c;
}

// Concatenate two strings
string add(string a, string b) {
return a + b;
}

// Add two doubles
double add(double a, double b) {
return a + b;
}
};

int main() {
Calculator calculator;

cout << "Add two integers: " << calculator.add(5, 10) << endl;
cout << "Add three integers: " << calculator.add(5, 10, 15) << endl;
cout << "Concatenate two strings: " << calculator.add("Hello", " World!") << endl;
cout << "Add two doubles: " << calculator.add(5.5, 10.5) << endl;

return 0;
}

Explanation of the Code

  1. Class Definition:
    The Calculator class contains four add methods with the same name but different parameters:
    • int add(int a, int b): Adds two integers.
    • int add(int a, int b, int c): Adds three integers.
    • string add(string a, string b): Concatenates two strings.
    • double add(double a, double b): Adds two double values.
  2. Compile-Time Decision:
    The compiler decides which version of the add method to call based on the number and types of arguments provided.
  3. Output:
    Add two integers: 15
    Add three integers: 30
    Concatenate two strings:
    Hello World! Add two doubles: 16

2. Run-Time Polymorphism (Function Overriding)

In function overriding, a derived class provides a specific implementation of a method that is already defined in its base class. This allows the program to decide at runtime which method to call based on the type of the object.

Example: Function Overriding

#include <iostream>
using namespace std;

class Car {
public:
void drive() {
cout << "The car is driving." << endl;
}
};

class Sedan : public Car {
public:
void drive() {
cout << "The sedan drives smoothly on the highway." << endl;
}
};

class SUV : public Car {
public:
void drive() {
cout << "The SUV drives comfortably on rough terrain." << endl;
}
};

class SportsCar : public Car {
public:
void drive() {
cout << "The sports car zooms at high speed on the track." << endl;
}
};

int main() {
Sedan sedan;
SUV suv;
SportsCar sportsCar;

sedan.drive();
suv.drive();
sportsCar.drive();

return 0;
}

Explanation of the Code

  1. Base Class (Car):
    The Car class contains a generic drive method.
  2. Derived Classes (Sedan, SUV, SportsCar):
    Each derived class overrides the drive method to provide its unique behavior.
  3. Output:
    The sedan drives smoothly on the highway.
    The SUV drives comfortably on rough terrain.
    The sports car zooms at high speed on the track.
  4. Dynamic Behavior:
    Even though all classes share the same drive method name, the behavior differs based on the object that calls the method.

Key Differences Between Function Overloading and Function Overriding

AspectFunction OverloadingFunction Overriding
DefinitionMethods with the same name but different parameters.A derived class redefines a method from the base class.
Binding TimeCompile-timeRun-time
ScopeWithin the same classAcross a base and derived class hierarchy
PurposeTo perform different tasks with the same name.To provide specific behavior in a subclass.

Benefits of Polymorphism

  1. Code Reusability:
    Functions or methods with the same name can work for different types or scenarios, reducing redundancy.
  2. Flexibility:
    Polymorphism allows you to add new functionality with minimal changes to the existing code.
  3. Maintainability:
    Polymorphism helps organize the code, making it easier to manage, debug, and extend.

Real-World Example: Payment System

#include <iostream>
using namespace std;

class Payment {
public:
virtual void makePayment(double amount) {
cout << "Processing payment of " << amount << " units." << endl;
}
};

class CreditCard : public Payment {
public:
void makePayment(double amount) override {
cout << "Paid " << amount << " using Credit Card." << endl;
}
};

class PayPal : public Payment {
public:
void makePayment(double amount) override {
cout << "Paid " << amount << " using PayPal." << endl;
}
};

int main() {
CreditCard creditCard;
PayPal payPal;

creditCard.makePayment(100.00);
payPal.makePayment(250.00);

return 0;
}

Detailed Explanation

  1. Base Class (Payment):
    Defines a generic makePayment method.
  2. Derived Classes (CreditCard, PayPal):
    Override the makePayment method to provide specific implementations.
  3. Output:
    Paid 100 using Credit Card.
    Paid 250 using PayPal.
  4. Real-World Application:
    This approach could be used in an e-commerce system where users select different payment methods.

Summary:

Polymorphism in C++ is a powerful concept that makes programs dynamic, flexible, and easier to maintain. By supporting both compile-time (overloading) and run-time (overriding) polymorphism, C++ allows developers to write reusable and adaptable code.

Leave a Reply

Your email address will not be published. Required fields are marked *

%d bloggers like this:
Verified by MonsterInsights