Let’s look at another topic from C++’s bag of new tricks: the default argument. A
How do you establish a default value? You must use the function prototype. Because the compiler looks at the prototype to see how many arguments a function uses, the function prototype also has to alert the program to the possibility of default arguments. The method is to assign a value to the argument in the prototype. For example, here’s the prototype fitting this description of left():
char * left(const char * str, int n = 1);
You want the function to return a new string, so its type is char*, or pointer-to-char. You want to leave the original string unaltered, so you use the const qualifier for the first argument. You want n to have a default value of 1, so you assign that value to n. A default argument value is an initialization value. Thus, the preceding prototype initializes n to the value 1. If you leave n alone, it has the value 1, but if you pass an argument, the new value overwrites the 1.
When you use a function with an argument list, you must add defaults from right to left. That is, you can’t provide a default value for a particular argument unless you also provide defaults for all the arguments to its right:
int harpo(int n, int m = 4, int j = 5); // VALID
int chico(int n, int m = 6, int j); // INVALID
int groucho(int k = 1, int m = 2, int n = 3); // VALID
For example, the harpo() prototype permits calls with one, two, or three arguments:
beeps = harpo(2); // same as harpo(2,4,5)
beeps = harpo(1,8); // same as harpo(1,8,5)
beeps = harpo (8,7,6); // no default arguments used
The actual arguments are assigned to the corresponding formal arguments from left to right; you can’t skip over arguments. Thus, the following isn’t allowed:
beeps = harpo(3, ,8); // invalid, doesn't set m to 4
Default arguments aren’t a major programming breakthrough; rather, they are a convenience. When you begin working with class design, you’ll find that they can reduce the number of constructors, methods, and method overloads you have to define.
Listing 8.9 puts default arguments to use. Note that only the prototype indicates the default. The function definition is the same as it would be without default arguments.
Listing 8.9. left.cpp
// left.cpp -- string function with a default argument
#include
const int ArSize = 80;
char * left(const char * str, int n = 1);
int main()
{
using namespace std;
char sample[ArSize];
cout << "Enter a string:\n";
cin.get(sample,ArSize);
char *ps = left(sample, 4);
cout << ps << endl;
delete [] ps; // free old string
ps = left(sample);
cout << ps << endl;
delete [] ps; // free new string
return 0;
}
// This function returns a pointer to a new string
// consisting of the first n characters in the str string.
char * left(const char * str, int n)
{
if(n < 0)
n = 0;
char * p = new char[n+1];
int i;
for (i = 0; i < n && str[i]; i++)
p[i] = str[i]; // copy characters
while (i <= n)
p[i++] = '\0'; // set rest of string to '\0'
return p;
}
Here’s a sample run of the program in Listing 8.9:
Enter a string:
forthcoming
fort
f
Program Notes
The program in Listing 8.9 uses new to create a new string for holding the selected characters. One awkward possibility is that an uncooperative user may request a negative number of characters. In that case, the function sets the character count to 0 and eventually returns the null string. Another awkward possibility is that an irresponsible user may request more characters than the string contains. The function protects against this by using a combined test:
i < n && str[i]