Optional/default Parameter or function overlading? Differences?

Hello folk!

In general. When do you use optional parameters for a function (first example in the class) or do you prefer to overload the functions (second example)?

Of course both function can't exists in the class at the same time (with overloading function the optional parameter is obsolet!), it tested it and want to understand the main difference...

thanks for your help

class calculate{
  public:
    int multiply(int a, int b=10){
    return a * b;
    }

    int multiply(int a, int b){
      return a*b;
    }


};


calculate calc = calculate();


void setup() {
  
  Serial.begin(115200);
  Serial.println(calc.multiply(5));
  Serial.println(calc.multiply(5,5));

}

void loop() {
  
}

Function overloading and default parameter values provide different functionality as illustrated by your example

For instance, you cannot call your second example without providing both parameters, and don't forget that optional parameters must be the last ones in the parameter list of the function

In general, function overloading is used when a different data type needs to be passed to a function or returned by the function

You may also like to look at the use of templates to make the function agnostic as to what type of data is passed to it, at least within reason

A small example

#include <Arduino.h>

template <typename varType>
void printBinBase(varType var, boolean splitBytes = false, boolean newLine = false )
{
  for (int bit = (sizeof(var) * 8) - 1; bit >= 0; bit--)
  {
    Serial.print( var >> bit & 1);
    if (splitBytes)
    {
      if (!(bit & 7))
      {
        Serial.print(" ");
      }
    }
  }
  if (newLine)
  {
    Serial.println();
  }
}

template <typename varType>
void printBin(varType var)
{
  printBinBase(var, false, false);
}

template <typename varType>
void printBinln(varType var)
{
  printBinBase(var, false, true);
}

template <typename varType>
void printBinBytes(varType var)
{
  printBinBase(var, true, false);
}

template <typename varType>
void printBinBytesln(varType var)
{
  printBinBase(var, true, true);
}

The functions printBin(), printBinln(), printBinBytes and printBinBytesln can be called with any scalar variable type.  Note the use of optional parameters in the printBinBase() function
2 Likes

They meet different conceptual needs. A good example is the print class.

You can see there the use of both at the same time

    size_t print(unsigned char, int = DEC);
    size_t print(int, int = DEC);
    size_t print(unsigned int, int = DEC);
    size_t print(long, int = DEC);
    size_t print(unsigned long, int = DEC);
    size_t print(double, int = 2);

The type of the first argument is different hence the use of overloaded functions and they have an optional parameter for formatting.

I would use optional parameters when it is indeed OK to have such default values for most common use.

I would use overloading if types are different or it’s a really different meaning - like you have a bit less arguments that have the same type but are conceptually different

1 Like

AFAIK, the "optional" argument isn't optional in the sense that it's "not implemented." It simply fills in the specified default if the user hasn't done so.

So both calculate.multiply(a) and calculate.multiply(a, 10) will produce exactly the same function call sequence at the machine code level, with the default argument setup.

But with overloaded functions, you're end up calling two separate functions, depending on the number of arguments. if you supply one argument, you call the version of the function with one argument. If you supply two, you call the version with two arguments.

The compiler can figure out what do do based on the class definition. But if you try to do both, it can't tell them apart...

1 Like

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.