Function overloading vs. function overriding in C++

In object-oriented programming, two important concepts that play a significant role in designing and implementing classes and functions are function overloading and function overriding. Both of these concepts provide ways to achieve polymorphism, which is the ability of objects of different classes to be treated as objects of a common base class. In C++, function overloading and function overriding are powerful tools that allow us to write more flexible and reusable code.

In this answer, we will delve into the differences between function overloading and function overriding, providing code examples to explain each concept.

Function overloading

Function overloading refers to the practice of defining multiple functions in the same scope with the same name but different parameter lists. The compiler differentiates between these functions based on the number or types of arguments they accept. This allows us to provide various ways to call a function depending on the program’s specific requirements.

Example

Let’s consider a simple example of function overloading:

#include <iostream>
using namespace std;
class MathOperations {
public:
int add(int a, int b) {
return a + b;
}
double add(double a, double b) {
return a + b;
}
};
int main() {
MathOperations math;
cout << math.add(2, 3) << std::endl; // Calls the int version of add
cout << math.add(2.5, 3.7) << std::endl; // Calls the double version of add
return 0;
}

In this example, the MathOperations class defines two add functions—one that accepts int parameters and another that accepts double parameters. The correct version of the function is called based on the argument types provided.

Explanation

Let’s go over the code in detail:

  • Line 5: We define a class named MathOperations.

  • Lines 7–9: We define a function, add, that calculates the sum of two integers and returns the result as an integer.

  • Lines 11–13: We define another function with the same name, add, but this one calculates the sum of two double parameters and returns the result as a double.

  • Line 17: Inside the main function, we create an instance of the MathOperations class named math.

  • Line 19: We call the add function with integer arguments 2 and 3. It calls the int add(int a, int b) version of the function. The result is then printed to the console.

  • Line 20: Similarly, we call the add function with double arguments 2.5 and 3.7. It calls the double add(double a, double b) version of the function. The result is then printed to the console.

Function overriding

Function overriding, on the other hand, occurs in the context of inheritance, and it allows a subclass to provide a specific implementation for a method that is already defined in its base class. In other words, the subclass can override the behavior of the method inherited from the base class.

Example

Consider the following example:

#include <iostream>
using namespace std;
class Shape {
public:
virtual void draw() {
cout << "Drawing a shape." << std::endl;
}
};
class Circle : public Shape {
public:
void draw() override {
cout << "Drawing a circle." << std::endl;
}
};
int main() {
Shape* shapePtr = new Circle;
shapePtr->draw(); // Calls the overridden draw method in Circle
delete shapePtr;
return 0;
}

In this example, we have a base class Shape with a virtual function draw(). The derived class Circle overrides the draw() method to provide its own implementation. When a Circle object is accessed through a pointer to a Shape, the overridden version of the function in the Circle class is called.

Explanation

Let’s go over the code in detail:

  • Line 5: We define the base class named Shape.

  • Lines 7–9: We create a virtual function, draw, in the base class Shape. The virtual keyword indicates that this function can be overridden by derived classes. This function prints the message "Drawing a shape." to the console.

  • Line 12: We define the derived class named Circle that inherits publicly from the Shape class.

  • Lines 14–16: We define the overridden draw function in the Circle class. The override keyword explicitly indicates that this function is intended to override the base class’s virtual function. This function prints the message "Drawing a circle." to the console.

  • Line 20: Inside the main function, we create a pointer shapePtr of type Shape* and assign it the address of a newly created Circle object. This is a demonstration of polymorphism, as a Circle object is being treated as a Shape.

  • Line 21: We call the draw method through the shapePtr. Since the shapePtr points to a Circle object, the overridden version of the draw function in the Circle class is called, resulting in "Drawing a circle." being printed.

  • Line 23: We deallocate the memory occupied by the dynamically allocated Circle object.

Key differences


Function overloading

Function overriding

Context

Provides multiple implementations of a function with the same name but different parameter lists in the same class

Provides a specialized implementation of a method in a derived class that has been defined in the base class

Scope

Occurs within the same class

Occurs in a derived class that inherits from a base class

Usage

Provides different ways to call a function with varying parameters

Provides specialized behavior in derived classes that extends or modifies the behavior of the base class

Polymorphism

Achieves compile-time polymorphism (also known as static polymorphism)

Achieves runtime polymorphism (also known as dynamic polymorphism) through virtual functions

Free Resources

Copyright ©2025 Educative, Inc. All rights reserved