默认实参
调用含有默认实参的函数时,可以包含该实参,也可以省略该实参。
使用 string 对象表示窗口的内容,为了使得窗口函数既能接纳默认值,也能接受用户指定的值,定义如下的形式:
typedef string::size_type sz; string screen(sz ht = 24,sz wid = 80, char backgrnd = ' ');
默认实参作为形参的初始值出现在形参列表中,一旦某个形参被赋予了默认值,它后面的所有形参都必须有默认值。
使用默认实参调用函数
想使用默认实参,只要在调用函数的时候省略该实参就可以了:
string window; window = screen();//等价于screen(24,80,' ') window = screen(66);//等价于screen(66,80,' ') window = screen(66, 256);//screen(66,256,' ') window = screen(66, 256, '#');//screen(66,256,'#')
函数调用时实参按其位置解析,默认实参负责填补函数调用缺少的尾部实参(靠右侧位置)。要想覆盖 backgrnd 的默认值,必须为 ht 和 wid 提供实参:
window = screen(, , '?');//错误:只能省略尾部的实参 window = screen('?');//调用screen('?',80,' ')
- ? 是个 char ,而函数最左侧形参的类型 string::size_type 是一种无符号整数类型,所以 char 类型可以转换成函数最左侧形参的类型。
- 当调用发生时,char 类型的实参隐式地转换成 string::size_type ,然后作为 hight 的值传递给函数。
- ? 对应的十六进制数是 0x3F,也就是十进制数的 63,所以该调用把值 63 传给了形参 height 。
设计含有默认实参的函数时,合理设置形参的顺序,尽量让不怎么使用默认值得形参出现在前面,而让那些经常使用默认值得形参出现在后面。
默认实参声明
函数声明通常放在头文件中,并且一个函数只声明一次,但是多次声明同一个函数也是合法的。
在给定的作用域中一个形参只能被赋予一次默认实参。
函数的后续声明只能为之前那些没有默认值的形参添加默认实参,而且该形参右侧的所有形参必须都有默认值:
//表示高度和宽度的形参没有默认值 string screen(sz, sz, char = ' ');
不能修改一个已经存在的默认值:
string screen(sz, sz, char = '*');//错误:声明重复
按照如下形式添加默认值:
string screen(sz = 24, sz = 80, char);//正确:添加默认实参
应该在函数声明中指定默认实参,并将该声明放在合适的头文件中。
默认实参初始值
局部变量不能作为默认实参。
只要表达式的类型能转换成形参所需的类型,该表达式就能作为默认实参:
//wd、def和hf的声明必须出现在函数之外 sz wd = 80; char def = ' '; sz ht(); string screen(sz = ht(), sz = wd, char = def); string window = screen();//调用screen(ht(),80,' ')
用作默认实参的名字在函数声明所在的作用域内解析,而这些名字的求值过程发生在函数调用时:
void f2() { def = '*';//改变默认实参的值 sz wd = 100;//隐藏了外层定义的wd,但是没有改变默认值 window = screen();//调用screen(ht(),80,'*') }
函数 f2() 内部改变了 def 的值,所以对 screen 的调用将会传递这个更新过的值。
函数声明了一个局部变量用于隐藏外层的wd,但是该局部变量与传递给 screen 的默认实参没有任何关系。

浙公网安备 33010602011771号