5.2.  Optional Arguments

[ fromfile: functions.xml id: defaultargs ]

Function parameters can have default values, making them optional. The default value for an optional argument can be a constant expression or an expression that does not involve local variables.

Parameters with default arguments must be the right-most (trailing) parameters in the parameter list. Trailing arguments with default values can be left out of the function call. The corresponding parameters will then be initialized with the default values.

From the viewpoint of the function, if it is called with one missing argument, that argument must correspond to the last parameter in the list. If two arguments are missing, they must correspond to the last two parameters in the list (and so forth).

Because an optional argument specifier applies to a function's interface, it belongs with the declaration, not the definition of the function if the declaration is kept in a separate header file. A function with default arguments can be called in more than one way. If all arguments for a function are optional, the function can be called with no arguments. Declaring a function with n optional arguments can be thought of as an abbreviated way of declaring n+1 functions, one for each possible way of calling the function.

In Example 5.3, the constructor for the Date class has three parameters; each parameter is optional and defaults to 0.

Example 5.3. src/functions/date.h

[ . . . . ]
class Date {
public:
    Date(int d = 0, int m = 0, int y = 0);
    void display(bool eoln = true) const;
private:
    int m_Day, m_Month, m_Year;
};
[ . . . . ]

<include src="src/functions/date.h" href="src/functions/date.h" id="dateh" mode="cpp"/>


The constructor definition shown in Example 5.4 looks the same as usual; no default arguments need to be specified there. If 0 turns out to be the value of any of the supplied arguments, it will be replaced with a sensible value derived from the current date.

Example 5.4. src/functions/date.cpp

#include <QDate>
#include "date.h"
#include <iostream>



Date::Date(int d , int m , int y ) 
: m_Day(d), m_Month(m), m_Year(y) {
    
    static QDate currentDate = QDate::currentDate(); 1
    
    if (m_Day == 0) m_Day = currentDate.day(); 
    if (m_Month == 0) m_Month = currentDate.month();
    if (m_Year == 0) m_Year = currentDate.year();
}
        

void Date::display(bool eoln) const {
    using namespace std;
    cout << m_Year << "/" << m_Month << '/' << m_Day;
    if (eoln)
        cout << endl;
}

1

We use Qt's QDate class only to get the current date.

<include src="src/functions/date.cpp" href="src/functions/date.cpp" id="datecpp" mode="cpp"/>


Example 5.5. src/functions/date-test.cpp

#include "date.h"
#include <iostream>

int main() {
    using namespace std;
    Date d1;
    Date d2(15);
    Date d3(23, 8);
    Date d4(19, 11, 2003);

    d1.display(false);
    cout << '\t';
    d2.display();
    d3.display(false);
    cout << '\t';
    d4.display();
    return 0;
}

<include src="src/functions/date-test.cpp" href="src/functions/date-test.cpp" id="datetestcpp" mode="cpp"/>


Example 5.5 demonstrates that by defining default values you are, in effect, overloading the function. The different versions of the function execute the same code, but with different values passed in for the later parameters.

So if you ran this program on May 14, 2011, it should show you the following output:

src/functions> qmake
src/functions> make
[ compiler linker messages ] 
src/functions> ./functions
2011/5/14       2011/5/15
2011/8/23       2003/11/19
src/functions>