某一函数的实参值如果绝大多数情况下都会使用,那么可以在函数声明中指定默认实参值,调用时就可以省略不写,编译器会帮忙自动补上。
规则:
1. 设计带默认参数的函数时要对参数排序,不带默认实参的参数排在前面,带默认实参的参数排在最后。
int ff(int a, int b = 0, int c = 0); // OK
char *init(int ht = 24, int wd, char bckgrnd); // Error: 默认实参不在形参列表的结尾!
2. 默认参数要么在函数声明里指定,要么在函数定义里指定,但是,只能指定一次。否则编译出错: 重定义默认参数。原因不知道。
// ff.h
int ff(int = 0);
// ff.cc
#include "ff.h"
int ff(int i = 0) { /* ... */ } // error
最佳写法:
// ff.h
int ff(int = 0); // 头文件声明时指定默认参数
// ff.cc
#include "ff.h"
int ff(int i) { /* ... */ } // OK,源文件不能再写出默认参数
3. 默认参数一般应当在函数声明里指定,且函数声明放在头文件中。如果默认参数放在函数的定义里,后果就是,只有包含该函数定义的source code里的函数调用可使用这些指定的默认参数。
函数调用的实参按位置解析,默认实参只能用来替换函数调用缺少的尾部实参。
string screenInit(string::size_type height = 24,string::size_type width = 80, char background = ' ' );
string screen;
screen = screenInit(); // equivalent to screenInit (24,80,' ')
screen = screenInit(66); // equivalent to screenInit (66,80,' ')
screen = screenInit(66, 256); // screenInit(66,256,' ')
screen = screenInit(66, 256, '#');
screen = screenInit(, , '?'); // error, can omit only trailing arguments
screen = screenInit( '?'); // calls screenInit('?',80,' ') 虽符合语法,但不符合code本意。
《C++ Primer》7.4.1