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 addcout << math.add(2.5, 3.7) << std::endl; // Calls the double version of addreturn 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 twodoubleparameters and returns the result as adouble.Line 17: Inside the
mainfunction, we create an instance of theMathOperationsclass namedmath.Line 19: We call the
addfunction with integer arguments2and3. It calls theint add(int a, int b)version of the function. The result is then printed to the console.Line 20: Similarly, we call the
addfunction with double arguments2.5and3.7. It calls thedouble 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 Circledelete 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 classShape. Thevirtualkeyword 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
Circlethat inherits publicly from theShapeclass.Lines 14–16: We define the overridden
drawfunction in theCircleclass. Theoverridekeyword 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
mainfunction, we create a pointershapePtrof typeShape*and assign it the address of a newly createdCircleobject. This is a demonstration of polymorphism, as aCircleobject is being treated as aShape.Line 21: We call the
drawmethod through theshapePtr. Since theshapePtrpoints to aCircleobject, the overridden version of thedrawfunction in theCircleclass is called, resulting in"Drawing a circle."being printed.Line 23: We deallocate the memory occupied by the dynamically allocated
Circleobject.
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