1、函数的参数为引用
需要注意的问题,变量的引用就是变量别名。注意非const和const,且传引用参数时不能进行类型转换。Page 204
int incr(int &val,string &s1,const string &s2)
{
cout << s1 << s2;
return ++val;
}
int main()
{
short v1 = 0;
const int v2 = 42;
int v3;
string s1;
const string s2;
v3 = incr(v1,s1,s2); //error,v1此时不能类型转换为int
v3 = incr(v2,s1,s2); //error,v2 不是const型
v3 = incr(v3,"hello world",s2); //error,不能将const型传给s1
v3 = incr(v3,s1,"hello world"); //ok
return 0;
}
2、数组作为函数的参数
数组作为函数参数,在函数中只会被看成是指针。函数只检查实参是不是指针、指针的类型和数组元素的类型是否匹配,而不会检查数组的长度。如果形参是数组的引用,编译器不会讲数组实参转化为指针而是数组的引用本身,数组的大小成为实参和形参类型的一部分。Page 207
void print_values1(int *ia){}
void print_values2(int ia[]){}
void print_values3(int ia[10]){}
void print_values4(int (&ia)[10]){}
int main()
{
int i=0,j[2] = {0,1},k[10]={0};
print_values2(&i); //ok,可能出现run_time error,因为在函数内部可能访问越界
print_values3(j); //ok,同上,print_value1\2\3 三个函数等价
print_values4(j); //error,j不是10 ints的数组
print_values4(k); //ok
return 0;
}
3、重载和局部申明
如果局部的声明一个函数,则该函数将屏蔽而不是重载在外层作用域中声明的同名函数。每一个版本的重载函数都应该在同一个作用域中声明。Page 230
void print(const string &){}
void print(double){} //重载
void fooBar(int val)
{
void print(int); //屏蔽了外部声明的两个重载的print函数
print("value:"); //error, print(const string&)被屏蔽了
print(val); //ok
print(3.14); //调用print(int)
}
4、重载的步骤
首先找到名字相同的为候选函数,然后参数匹配(包括隐式类型转换后)的为可行函数,再寻找最佳匹配,即参数精确匹配优于其他的函数。如果最佳匹配函数不是唯一的那么产生二义性,编译错误。Page 232
void f(double ,int){}
void f(int ,double){}
int main()
{
f(3.14,3); //ok,两个函数都可行,但是第二个为最佳匹配
f(3.14,3.14); //error,两个函数的匹配程度相同,最佳匹配不唯一
return 0;
}
5、重载和const
仅当形参时引用或指针时,形参是否为const才有影响。
void f1(int&){}
void f1(const int&){} //ok
void f2(int *){}
void f2(int const*){} //ok
void f2(int *const){} //error,重定义,const是修饰指针本身,指针本身是以副本的形式传递