If we create two or more members having the same name but different in number or type of parameter, it is known as C++ overloading. In C++, we can overload:
- methods,
- constructors, and
- indexed properties
It is because these members have parameters only.
Types of overloading in C++ are:
- Function overloading
- Operator overloading
C++ Function Overloading
Function overloading refers to the practice of defining multiple functions with identical names but varying parameters in C++. This technique involves redefining a function by utilizing either distinct argument types or a differing quantity of arguments. These distinctions are essential for enabling the compiler to distinguish between the functions effectively.
The benefit of Function overloading lies in its ability to enhance the clarity of the code by eliminating the necessity to employ distinct names for identical operations.
C++ Function Overloading Example
Let's explore a basic illustration of function overloading by modifying the number of arguments in the add function.
// Demonstrating function overloading with varying number of arguments.
#include <iostream>
using namespace std;
class Cal {
public:
static int add(int a,int b){
return a + b;
}
static int add(int a, int b, int c)
{
return a + b + c;
}
};
int main(void) {
Cal C; // class object declaration.
cout<<C.add(10, 20)<<endl;
cout<<C.add(12, 20, 23);
return 0;
}
Output:
30
55
Let's examine a straightforward example where the data types of the arguments differ.
// Demonstrating function overloading using various argument types.
#include<iostream>
using namespace std;
int mul(int,int);
float mul(float,int);
int mul(int a,int b)
{
return a*b;
}
float mul(double x, int y)
{
return x*y;
}
int main()
{
int r1 = mul(6,7);
float r2 = mul(0.2,3);
std::cout << "r1 is : " <<r1<< std::endl;
std::cout <<"r2 is : " <<r2<< std::endl;
return 0;
}
Output:
r1 is : 42
r2 is : 0.6
Function Overloading and Ambiguity
When the compiler faces uncertainty in determining which overloaded function to call, this scenario is referred to as function overloading.
When the compiler detects an ambiguity error, it halts the program execution.
Causes of Function Overloading:
- Type Conversion.
- Function with default arguments.
- Function with pass by reference.
- Type Conversion:
Let's see a simple example.
#include<iostream>
using namespace std;
void fun(int);
void fun(float);
void fun(int i)
{
std::cout << "Value of i is : " <<i<< std::endl;
}
void fun(float j)
{
std::cout << "Value of j is : " <<j<< std::endl;
}
int main()
{
fun(12);
fun(1.2);
return 0;
}
The aforementioned example demonstrates an issue where the error "call of overloaded 'fun(double)' is ambiguous" arises. When calling fun(10), the first function is invoked, while fun(1.2) triggers the second function as anticipated. However, this discrepancy occurs because in C++, all floating-point constants are inherently interpreted as double rather than float. By adjusting the data type from float to double, the program functions correctly, illustrating a type conversion from float to double.
- Function with Default Parameters
Let's see a simple example.
#include<iostream>
using namespace std;
void fun(int);
void fun(int,int);
void fun(int i)
{
std::cout << "Value of i is : " <<i<< std::endl;
}
void fun(int a,int b=9)
{
std::cout << "Value of a is : " <<a<< std::endl;
std::cout << "Value of b is : " <<b<< std::endl;
}
int main()
{
fun(12);
return 0;
}
The previously mentioned example highlights an issue regarding an ambiguous function call. The function fun(int a, int b=9) can be invoked either by passing one argument, such as fun(12), or by passing two arguments, like fun(4,5). On the other hand, the function fun(int i) is called with a single argument. This situation leads to ambiguity for the compiler in distinguishing between fun(int i) and fun(int a, int b=9).
- Function utilizing pass by reference
Let's see a simple example.
#include <iostream>
using namespace std;
void fun(int);
void fun(int &);
int main()
{
int a=10;
fun(a); // error, which f()?
return 0;
}
void fun(int x)
{
std::cout << "Value of x is : " <<x<< std::endl;
}
void fun(int &b)
{
std::cout << "Value of b is : " <<b<< std::endl;
}
The error message "call of overloaded 'fun(int&)' is ambiguous" indicates a situation where the compiler cannot determine which function to call. The ambiguity arises because there are two functions: one taking an integer argument and the other taking a reference parameter as an argument. Since there is no syntactical difference between the two function signatures fun(int) and fun(int &), the compiler is unsure which function the user intends to use.
C++ Operators Overloading
Operator overloading is a form of compile-time polymorphism that involves redefining operators to give special significance to user-defined data types. This technique allows for the customization of various operators in C++. It enables the execution of operations on user-defined data types, such as adding variables of these types to built-in data types within C++.
The benefit of operator overloading is the capability to execute various operations using the same operand.
Operator that cannot be overloaded are as follows:
- Scope operator (::)
- Sizeof
- member selector(.)
- member pointer selector(*)
- ternary operator(?:)
Syntax of Operator Overloading
return_type class_name : : operator op(argument_list)
{
// body of the function.
}
Where the return type signifies the data type of the value that the function returns.
class_name is the name of the class.
The operator function is a function that overloads a specific operator, with 'op' representing the operator being overloaded, and 'operator' being the keyword used.
Rules for Operator Overloading
- Existing operators can only be overloaded, but the new operators cannot be overloaded.
- The overloaded operator contains atleast one operand of the user-defined data type.
- We cannot use friend function to overload certain operators. However, the member function can be used to overload those operators.
- When unary operators are overloaded through a member function take no explicit arguments, but, if they are overloaded by a friend function, takes one argument.
- When binary operators are overloaded through a member function takes one explicit argument, and if they are overloaded through a friend function takes two explicit arguments.
C++ Operators Overloading Example
Let's explore a basic illustration of operator overloading in C++. In this instance, the operator function void operator ++ is implemented within the Test class.
// program to overload the unary operator ++.
#include <iostream>
using namespace std;
class Test
{
private:
int num;
public:
Test(): num(8){}
void operator ++() {
num = num+2;
}
void Print() {
cout<<"The Count is: "<<num;
}
};
int main()
{
Test tt;
++tt; // calling of a function "void operator ++()"
tt.Print();
return 0;
}
Output:
The Count is: 10
Explore a basic illustration of how to overload binary operators.
// program to overload the binary operators.
#include <iostream>
using namespace std;
class A
{
int x;
public:
A(){}
A(int i)
{
x=i;
}
void operator+(A);
void display();
};
void A :: operator+(A a)
{
int m = x+a.x;
cout<<"The result of the addition of two objects is : "<<m;
}
int main()
{
A a1(5);
A a2(4);
a1+a2;
return 0;
}
Output:
The result of the addition of two objects is : 9