Difference Between Function Overloading and Overriding in C++
In C++, two or more functions can have the same name if the number or the type of parameters are different. This is function overloading. Function overriding is the redefinition of a base class function in its derived class with the same signature. Both overloading and overriding in C++ contribute to the flexibility and the polymorphic behavior of the code. Let us discuss overloading and overriding in C++ in great detail.
What is Function Overloading in C++?
Let’s consider a situation: you want to create a program that would return the area of the rectangle. If you are provided with length(say x) and breadth(say y), you would return x*y. You would probably write this code:
Now, you wish to calculate the area of a square using the same function. If you are provided with x only(just one argument), you would assume that the area of square is being calculated and returnx*x. You would write the code something similar to this:
C++ can distinguish between the two contexts of function calls because the number of arguments differs in both instances.
Apart from distinguishing based on the number of arguments, C++ can also distinguish the function calls based on the data type of the arguments passed to the function. Suppose, you want to code for the area of the circle if the user provided a floating value input. If a float value is passed, you would return the area of the circle (3.14 * r * r). For an int value, you would return x * x as before. You can define a third function that distinguishes based on the data type passed.
Side Note: One subtle problem with distinguishing based on the data type of the function is type casting (i.e., a char type can be promoted to int or float or double). The C++ compiler follows a series of priorities when matching the function application:
- It first tries to match the exact type (int to int/float to float).
- If no match is found, it promotes the data type and retries (conversion between int to char and char to int or float to double and double to float).
- If still no match is found, the C++ compiler throws an error.
As can be seen, if functions are :
And if you called foo(‘a’, ‘a’) or foo(21, 21), the function call would be ambiguous, and the C++ compiler would throw an error; however, foo(‘a’, 21) or foo(21, ‘a’) would compile correctly. This is because the (char, char) or (int, int) can be internally promoted to either (char, int) or (int, char), which is why it is ambiguous. However, (char, int) and (int, char) have specific implementations.
This is what we call Function Overloading. We overload (redefine) the function alias to have different implementations and distinguish these based on the number of arguments or the data type.
These function overloading instances are a type of compile time polymorphism. The C++ compiler at compile time can easily deduce which function is being called by inspecting based on the above conditions. Internally, both the functions have different signatures (signature meaning the structure/layout of the function – the number/type of argument it accepts) and the compiled object code references the correct functions.
What is Function Overriding in C++?
Say, instead of writing functions, we want to define an OOP-based solution. First, we need to have a map of how we want to design these structures.
One solution is to have a Rectangle class. Since we know that a Square is a Rectangle, we can create a subclass Square off a class Rectangle.
Output:
We know that child classes inherit all public data and methods from the parent class. So the Square class also inherits the area function. However, we redefine the area function as side * side. This redefinition of the area function is an example of function overriding. C++ knows that you specifically redefined the area function for the Square class. This overriding of function is a type of runtime polymorphism.
C++ distinguishes the function call at runtime instead of knowing it during compilation because the function signature is similar at compile time.
Difference between Overloading and Overriding in C++
As we’ve seen before, function overloading and overriding play similar roles. They both provide an abstraction over the interface so that the end user doesn’t have to think much about the context and pass in the arguments. However, there are subtle differences between the two approaches.
Overloading vs Overriding in C++:
Function Overloading | Function Overriding |
---|---|
Function overloading can be used in normal functions as well as in classes (e.g., constructor overloading is a classic example where you would vary the number/type of arguments for different initializations). | Function overriding applies exclusively to an inherited class (or in other words a subclass). |
Function overloading is resolved at compile time. | Function overriding is resolved at run time. |
Overloaded functions are in the same scope. | Overridden functions are in different scopes. |
Overloaded functions have different function signatures. | Overridden functions have the same function signatures. |
Conclusion
- Function overloading and overriding both seek to improve the interface and provide a consistent interface that should be intuitive to the user. They are used in different contexts.
- Function overloading is used when we want multiple functions providing a similar implementation.
- Function overriding is used when we want to add some additional functionality on top of base class implementation.