【C++】默认实参(缺省参数)

内容来自《C++ Primer(第5版)》6.5.1 默认实参


目录

使用默认实参调用函数

默认实参声明

默认实参初始值


某些函数有这样一种形参,在函数的很多次调用中它们都被赋予一个相同的值,此时,我们把这个反复出现的值称为函数的默认实参(default argument)。调用含有默认实参的函数时,可以包含该实参,也可以省略该实参。

例如,我们使用string对象表示窗口的内容。一般情况下,我们希望该窗口的高、宽和背景字符都使用默认值。但是同时我们也应该允许用户为这几个参数自由指定与默认值不同的数值。为了使得窗口函数既能接纳默认值,也能接受用户指定的值,我们把它定义成如下的形式:

typedef string::size_type sz;
string screen(sz ht = 24, sz wid = 80,char backgrnd = ' ');

其中我们为每一个形参都提供了默认实参,默认实参作为形参的初始值出现在形参列表中。我们可以为一个或多个形参定义默认值,不过需要注意的是,一旦某个形参被赋予了默认值,它后面的所有形参都必须有默认值。

使用默认实参调用函数

如果我们想使用默认实参,只要在调用函数的时候省略该实参就可以了。例如,screen函数为它的所有形参都提供了默认实参,所以我们可以使用0、1、2或3个实参调用该函数:

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,然后作为height的值传递给函数。在我们的机器上,'?'对应的十六进制数是0x3F,也就是十进制数的63,所以该调用把值63传给了形参height。

当设计含有默认实参的函数时,其中一项任务是合理设置形参的顺序,尽量让不怎么使用默认值的形参出现在前面,而让那些经常使用默认值的形参出现在后面。

默认实参声明

对于函数的声明来说,通常的习惯是将其放在头文件中,并且一个函数只声明一次,但是多次声明同一个函数也是合法的。不过有一点需要注意,在给定的作用域中一个形参只能被赋予一次默认实参。换句话说,函数的后续声明只能为之前那些没有默认值的形参添加默认实参,而且该形参右侧的所有形参必须都有默认值。假如给定

//表示高度和宽度的形参没有默认值
string screen(sz, sz, char = ' ');

我们不能修改一个已经存在的默认值:

string screen(sz, sz, char = '*');//错误:重复声明

但是可以按照如下形式添加默认实参:

string screen(sz = 24, sz = 80, char);//正确:添加默认实参

Best Practices

通常,应该在函数声明中指定默认实参,并将该声明放在合适的头文件中。

默认实参初始值

局部变量不能作为默认实参。除此之外,只要表达式的类型能转换成形参所需的类型,该表达式就能作为默认实参:

//wd、def和ht的声明必须出现在函数之外
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的默认实参没有任何关系。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值