默认参数
默认参数定义
C++ 一项新的内容是:默认参数
默认参数是指:当函数调用中省略了实参时自动使用的一个值
来看一个例子
void f1(int n,int p=8);
......
int main(void)
{
...
f1(a);
...
}
void f1(int n,int p)
{
......
}
如上例所示,当函数调用时,如果有第二个这个值,将覆盖默认值使用传递的值,如果没有则使用默认值。
实现
也如同上例所示,默认参数的实现需要借助函数原型,由于编译器通过查看函数原型来了解函数使用的参数数目,所以,也可以将默认参数告诉编译器,只需要将值赋给原型中的函数,就可以实现默认参数。
看一个例子:
可以看出,以上所说的特性。
注意
对于带参数列表的函数,必须从左向右添加默认值,也就是说,如果想要为某个参数添加默认值,那么需要先为这个参数后面的所有参数添加默认值。
int f1(int a,int b,int c=8);
int f1(int a,int b=6,int c=8);
int f1(int a,int b=7,int c);
也就是说:对于上面的定义最后一个是无效的。
如果这样定义,那么编译器将会报错。
另外,在对于调用函数为形参赋值时,实参从左到右依次为形参赋值,不可跳过。
f1(a,,8);
像是以上这种是不允许的,编译器同样会报错。
默认参数提供了一种便捷的方式,在设计类时,通过使用默认参数,可以减少定义的析构函数、方法以及方法重载的数量。
小PS: 对于字符串的测试可以这样写:
while(m<=n&&str[m])
m++;
while(m<=n&&str[m]!='\0')
m++;
由于非零为真,而'\0'
的ASCII码是0,因此可以这样写。
函数重载
函数多态是C++在C语言基础上新增的功能。默认参数能够使用不同数目的参数调用一个函数,而函数多态即函数重载使用户可以使用多个同名的函数。
定义
C++根据上下文来确定函数重载的版本。
函数重载的关键是函数的参数列表——也称函数特征标。
如果两个函数的参数数目和类型均相同,排列顺序也相同,那么两个函数的特征标相同,特征标的相同与否无关于函数名。如果两个函数的名称相同,但是他们的特征标不同,那么这种情况是允许的,即是函数重载。
int f(int a,int b);
int f(double a,float b);
int f(const string,char* name);
以上三个函数可以在一个文件中定义不会冲突,因为他们的特征标不同,函数重载。在使用重载函数时,需要在函数调用中使用正确的参数,通过匹配相符的参数列表确认使用的具体函数。
函数重载时参数的类型转换
假设有上例中函数定义,当有如下函数调用时,会发生什么呢:
int f(int a,int b);
int f(double a,float b);
int f(const string,char* name);
unsigned int a=8;
float b=2.3;
char ch='A';
char *str1="abc";
f(a,b);
f(str1,str1);
f(b,b);
f(ch,a);
上面函数调用的参数列表并不与任何函数定义的原型匹配,但是函数的匹配并不会因此停止,C++尝试使用标准类型转换强制进行匹配。
如果对于f(a,b)
来讲,有唯一对应函数原型int f(int a,int b);
那么将进行类型转换,把unsigned int
类型和 float
类型转换为int
类型。
但是,这个函数调用可以对应两个函数原型,都可以通过类型转化来令函数符合原型,在这种情况下,C++将拒绝这种函数调用,并且报错。
***注意:***有一些看起来不同的函数特征标,实际上他们是相同的:
比如说:
void f(double x);
void f(double& x);
也即是说,编译器视类型引用和类型本身为同一个特征标。
还有
int f(int a);
int f(const int a);
上面的两个示例特征标也是相同的。
匹配函数时,并不区分const
和非const
变量
然而却还是有一个问题:
一个问题
以上一个示例可以运行,另一个却不能,问题尚未找到。
而对于能够重载的那个示例:在函数匹配原型时,根据实际参数是否为const
变量来匹配对应的函数原型。
注意: 可以将非const
变量赋值给const
变量,因为这样做不会有什么后果,只是在子函数中限制这个参数不可改变,即使使用引用或者指针等,也不会改变父函数中传递的值。但是不能将const
值赋值给非const
变量,原因之一,当函数传递为指针或者引用时,子函数或将试图修改父函数中的const
变量或者值,这显然是不允许和不被希望的。
函数的重载与否与特征标有关,而与返回类型无关:
long f(int a);
double f(int a);
以上两个函数声明是不兼容的,他们不能够同时声明定义,因为他们的特征标相同。
何时使用函数重载
函数重载不要滥用,当函数需要执行相同任务,但是所使用的数据形式不相同时,更适合使用函数重载,也应该思考是否可以用默认参数来替代函数重载的功能,也可以考虑函数模板。
对于C++如何跟踪重载函数,资料参考: