Understanding Function Overloading In C++ With Examples

Understanding Function Overloading In C++ With Examples
Understanding Function Overloading In C++ With Examples

Introduction 

What would happen if two functions with the same name are declared? Would this throw an error? 

If the parameters and their order are exactly the same, then yes. Otherwise, it leads to a situation known as function overloading.

Function overloading is when more than one function has the same name but different signatures. In this case, the function call decides which overloaded function to run. 

Function Overloading can be achieved in the following ways:

  • A different number of parameters
  • Different data types of parameters

Examples of Function Overloading in C++ 

Let’s look at some examples to understand function overloading in C++.

1. Function Overloading in c++ can be achieved by specifying a different number of parameters in the function definition.

Example:

#include<iostream>  
using namespace std;  

// function with one argument
void display(int a) {
  cout << "a = "<<a<<endl;
}

// function with two argument
void display(int a, int b) {
  cout << "a = "<<a<<" and b = "<<b<<endl;
}

int main() {
  display(5);
  display(5,10);
  return 0;
}

Output:

a = 5
a = 5 and b = 10

In the above program, there are two display() functions. The first one consists of a single int parameter and the second one has two int parameters. display() function gets overloaded in this case because of a different number of parameters.

2. Function Overloading in c++ can be achieved by specifying different types of parameters in the function definition.

blog banner 1
#include<iostream>  
using namespace std;  

// function with (int,int) parameters
void multiply(int a, int b) {
  cout << "a * b = "<<a*b<<endl;
}

// function with (double,double) parameters
void multiply(double a, double b) {
  cout << "a * b = "<<a*b<<endl;
}

// function with (int,double) parameters
void multiply(int a, double b) {
  cout << "a * b = "<<a*b<<endl;
}

// function with (double,int) parameters
void multiply(double a, int b) {
  cout << "a * b = "<<a*b<<endl;
}

int main() {
  multiply(5, 10);
  multiply(1.2,0.5);
  multiply(3,0.4);
  multiply(0.5, 3);
  return 0;
}

Output:

a * b = 50
a * b = 0.6
a * b = 1.2
a * b = 1.5

In the above program, there are four multiply() functions. All four have different types of data types in a different order. The multiply() function gets overloaded in this case because of different parameter types.

Which function to run?

When an overloaded function is called, the compiler determines the most appropriate function definition to use, by comparing the number of arguments and argument types you have used to call the function. This process of selecting the most appropriate overloaded function is called overload resolution.

The steps of overload resolution are:

  • Find suitable functions via name lookup. These functions are called candidate functions.
  • Remove invalid candidate functions from the list. The left out functions are called viable functions. A candidate function becomes invalid when:
    • The passed argument count does not match the parameter list.
    • Passed arguments types do not match the function parameter.                            
  • Viable functions are then ranked.
    • Ranking order: Exactly match parameters >  parameters matched after standard conversions >  parameters matched after user-defined conversions
  • If the best match is found from the viable function list, then that function is executed; else the compiler returns an error.     

Note: Function overloading is independent of the return type.

Polymorphism and Function Overloading

The word “Polymorphism” is a combination of two words:  “poly” meaning “many” and “morphs” meaning “forms”. It simply means more than one form. That is, the same function or operator behaves differently in different scenarios.

Types of polymorphism

  • Compile-time polymorphism: Polymorphism which is achieved at compile time, is called compile-time polymorphism. Function overloading and operator overloading are used to attain compile-time polymorphism.
  • Runtime polymorphism: It is achieved when the object’s method is invoked at the run time. Function overriding is used to achieve this.

Polymorphism basically means taking multiple forms. In function overloading, we have a function that has many forms, each with a different number or type of parameter. Depending on the parameter, a suitable function call is made at compile time. Hence it is a compile-time(or static) polymorphism.

Advantages of Function Overloading

Some of the benefits of function overloading are:

  • Programs execution becomes faster.
  • Smooth and simple code flow.
  • Code maintenance becomes easier.
  • Improves code readability.
  • Saves memory space.
  • Code reusability achieved.
  • It brings flexibility to the code.
  • It can perform different operations, and hence it eliminates the use of different function names for the same kind of operations.

Disadvantages of Function Overloading

Some of the disadvantages of function overloading are:

1. Functions with different return types cannot be overloaded as they can have the same parameter definition.

Consider the case below:

public void num(int a) {
cout << "a = "<<a<<endl;
}

public int num(int a) {
return a + 10;
}

In this case, the compiler cannot decide which function to call as both have the same parameter definition even after having different return types.

2. It cannot overload functions with the same name and parameter if any one of them is a static member function declaration.

The static member functions can’t be overloaded because the definition must be the same for all class instances. If an overloaded function has many definitions, none of them can be made static

Overloading Ambiguity

The situation in which the compiler is unable to decide the appropriate overloaded function is called overloading ambiguity. In that case, the compiler won’t run the program.

Overloading ambiguity occurs in the following cases:

1. Type conversion

In C++, some data types will get automatically converted to some other data type if the suffix is not mentioned. In that case, the compiler cannot decide which function to call, and an ambiguity error occurs.

#include<iostream>  
using namespace std;  

void function(float) {
   cout << "Data Type: float\n";
}

void function(int) {
   cout << "Data Type: int\n";
}

int main() {
  function(1.0);
  function(1);
  return 0;
}

Error:

In C++, all floating-point constants are considered as double unless explicitly specified by a suffix, so the above code generates a type conversion error.  To overcome this problem, we can add a suffix to the passed value.

#include<iostream>  
using namespace std;  

void function(float a) {
   cout << "Data Type: float\n";
}

void function(int a) {
   cout << "Data Type: int\n";
}

int main() {
  // float argument passed
  function(1.0f);
  // int argument passed
  function(1);
  return 0;
}

2. Function with default arguments

When a function is overloaded with a default argument, the compiler gets confused if another function satisfies the parameter conditions.

In the example below, when add(a) is called , both add(int a) and add(int a, int b = 10) conditions are fulfilled. In this case, the compiler cannot select which function to call and produces an ambiguity error.

Example:

#include<iostream>  
using namespace std;  

int add(int a) {
  int b = 10;
  return a + b;
}

// function contains a default argument
int add(int a, int b = 10) {
  return a + b;
And }

int main() {
  int a = 5;
  cout << "a + b = "<<add(a)<<endl;
  return 0;
}

Error:

3. Function with pass by reference

When a function is overloaded with a reference parameter, the compiler gets confused as there is no syntactical difference between both functions.

#include<iostream>  
using namespace std;  

void display(int a) {
  cout << "a = "<<a<<endl;
}

void display(int &a) {
  cout << "a = "<<a<<endl;
}

int main() {
  int a = 5;
  display(a);
  return 0;
}

Error:

There is no syntactical difference between display(a) and display(&a). And in this case, the compiler will not be able to decide which function to call, resulting in an error.

Can the main() function be overloaded in C++?

Yes, the main() function can be overloaded in C++. To overload the main() function, we have to use a class and declare the main() function as a member function.

Example:

#include <iostream>
using namespace std;

// create a Main class and declare main() as member function
class Main {
public:
    int main(int a) {
         cout<<"a = "<<a<<endl;
        return 0;
    }

    int main(int a ,int b) {
        cout<<"a = "<<a<<"; b = "<<b<<endl;
        return 0;
    }
};

int main() {
    Main object;
    object.main(5);
    object.main(5,10);
    return 0;
}

Output:

a = 5
a = 5; b = 10

Frequently Asked Questions

What are the different types of overloading?

There are two types of overloading: Function overloading and operator overloading.

What is operator overloading?

It is a compile-time polymorphism used to redefine the operator and provide the operator with a special meaning for a data type.

What is the minimum number of functions required to achieve function overloading in C++?

At least two functions with the same name and different parameter signature is required to achieve function overloading in C++.

What is function overriding?

When the child class and parent class have a function with the same name and parameters, it is called Function Overriding.

Which Object Oriented Programming Concept is supported by function overloading in C++?

Polymorphism

Is function overloading a compile-time polymorphism or runtime polymorphism?

The compiler selects the appropriate function at compile-time, and hence it is a compile-time polymorphism.

How to achieve function overloading in C++?

Function overloading in C++ can be achieved by declaring more than one function has the same name but with different numbers and types of parameters.

Key Takeaways

This blog attempted to give a detailed explanation of function overloading in C++. Concepts like overloading resolution, overloading ambiguity, polymorphism have been covered along with some examples of function overloading in C++.

By Hari Sapna Nair