MFC Programmer's SourceBook : Thinking in C++
Bruce Eckel's Thinking in C++, 2nd Ed Contents | Prev | Next

Summary

Both function overloading and default arguments provide a convenience for calling function names. It can seem confusing at times to know which technique to use. For example, in the BitVector class it seems like the two bits( ) functions could be combined into a single version:

int bits(int sz = -1);

If you called it without an argument, the function would check for the -1 default and interpret that as meaning that you wanted it to tell you the current number of bits. The use appears to be the same as the previous scheme. However, there are a number of significant differences that jump out, or at least should make you feel uncomfortable.

Inside bits( ) you’ll have to do a conditional based on the value of the argument. If you have to look for the default rather than treating it as an ordinary value, that should be a clue that you will end up with two different functions inside one: one version for the normal case, and one for the default. You might as well split it up into two distinct function bodies and let the compiler do the selection. This results in a slight increase in efficiency, because the extra argument isn’t passed and the extra code for the conditional isn’t executed. The slight efficiency increase for two functions could make a difference if you call the function many times.

You do lose something when you use a default argument in this case. First, the default has to be something you wouldn’t ordinarily use, -1 in this case. Now you can’t tell if a negative number is an accident or a default substitution. Second, there’s only one return value with a single function, so the compiler loses the information that was available for the overloaded functions. Now, if you say

int i = bv1.set(10);

the compiler will accept it and no longer sees something that you, as the class designer, might want, to be an error.

And consider the plight of the user, always. Which design will make more sense to users of your class as they peruse the header file? What does a default argument of -1 suggest? Not much. The two separate functions are much clearer because one takes a value and doesn’t return anything and the other doesn’t take a value but returns something. Even without documentation, it’s far easier to guess what the two different functions do.

As a guideline, you shouldn’t use a default argument as a flag upon which to conditionally execute code. You should instead break the function into two or more overloaded functions if you can. A default argument should be a value you would ordinarily put in that position. It’s a value that is more likely to occur than all the rest, so users can generally ignore it or use it only if they want to change it from the default value.

The default argument is included to make function calls easier, especially when those functions have many arguments with typical values. Not only is it much easier to write the calls, it’s easier to read them, especially if the class creator can order the arguments so the least-modified defaults appear latest in the list.

An especially important use of default arguments is when you start out with a function with a set of arguments, and after it’s been used for a while you discover you need to add arguments. By defaulting all the new arguments, you ensure that all client code using the previous interface is not disturbed.

Contents | Prev | Next


Go to CodeGuru.com
Contact: webmaster@codeguru.com
© Copyright 1997-1999 CodeGuru