简介
Tips:一旦某个形参被赋予了默认值,那么它后面的所有形参都必须有默认值。
某些函数包含一类形参,它们在函数的很多次调用中都被赋予了一个相同的值,我们将这个反复出现的值称为函数的默认实参。调用含有默认实参的函数时,可以包含该实参,也可以省略该实参:
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, '#')
编码规范:只允许在非虚函数中使用默认实参,且必须保证默认实参的值始终一致。不建议使用默认实参,一般情况下建议使用函数重载(默认实参实际上就是函数重载语义的另一种实现方式),因为默认实参会干扰函数指针,导致函数签名与调用点的签名不一致,而函数重载不会导致这样的问题。
Tips:可以在构造函数中使用默认实参,毕竟不可能取得它们的地址。
声明
在给定的作用域内,一个形参只能被赋予一次默认实参(因为两个函数都是最佳匹配,会导致二义性调用的错误),但是可以给其他的形参添加默认实参:
typedef string::size_type sz;string screen(sz, sz, char = ' ');string screen(sz, sz, char = '*'); // 错误: 重复声明string screen(sz = 24, sz = 80, char); // 正确: 添加默认实参
表达式作为默认实参的初始值
局部变量不能作为默认实参,但是只要表达式的类型能转换成形参所需的类型,那么该表达式就能作为默认实参初始值:
sz wd = 80;char def = ' ';sz ht();// 函数声明string screen(sz = ht(), sz = wd, char = def);// 函数调用: 等价于screen(ht(), 80, ' ')string window = screen();// 函数调用void foo() {def = '*'; // 改变默认实参def的值sz wd = 100; // 隐藏了外层定义的wd, 但是没有改变默认值window = screen(); // 等价于screen(ht(), 80, '*')}
