函数重载:如果同一个作用域内的几个函数名字相同但形参列表不同,我们称之为重载函数。
main函数不能重载。返回值不能用来判断函数是否重载。
参数列表不同:参数的个数不同;参数的类型不同;参数的顺序不同;
void print(int a);
void print(double b);
int print(int a,int b);
重载和const形参:
顶层const不影响传入函数的对象。一个拥有顶层const的形参无法和一个没有顶层const的形参区分开来。
顶层const:表示指针本身是常量;
底层const:表示指针所指向的对象是常量;
void func(int a);
void func(const int a); //重定义了func,const在引用或指针变量中会有影响,但在普通类型中没有影响。
void func(int *const a); //重定义了func,a是一个顶层const。
void func(int const *a); //重载func。
另一方面,如果形参是某种类型的指针或引用,则通过区分其指向的是常量对象
还是非常量对象可以实现函数重载,此时的const是底层的。
void func(int &a); //形参a能接受非常量的实参,而不能接受常量实参
void func(const int &a); //构成重载,传递给a的实参能接受常量和非常量的实参
void func(int *a);
void func(const int *a); //a是一个底层const,可以构成重载
重载对作用域的一般性质并没有什么改变:如果我们在内层作用域中声明名字,
它将隐藏外层作用域中声明的同名实体。在不同作用域中无法重载函数名:
string read(); //在全局作用域中声明一个名为read的函数
void print(const string &);
void print(double);
void func(int val)
{
bool read = false; //在局部作用域中声明了一个名为read的布尔变量
string s = read(); //错误的,此时的read是一个布尔变量,隐藏了全局作用域中的read函数
void print(int); //在局部作用域中声明了一个名为print的函数,参数为int
print("hello"); //错误的,此时局部的print函数,隐藏了全局的print函数,参数不匹配
print(val); //调用了print(int)
print(7.45); //调用了print(int),print(double)被隐藏了。
}
void print(const string &);
void print(double);
void print(int);
void func(int val)
{
print("hello"); //调用了print(const string &)
print(val); //调用了print(double)
print(7.45); //调用了print(int)
}
默认实参:在函数的很多次调用中他们都被赋予一个相同的值,这个反复出现的值,称为函数的默认实参。
使用默认实参调用函数:
int func(int a=10,char b='b',double c=4.1);
在函数调用时,函数实参是按其位置解析的,默认实参负责填充函数调用缺少的尾部参数。
int tmp;
tmp = func(66); //等价于func(66,'b',4.1);
tmp = func(66,'a'); //等价于func(66,'a',4.1);
tmp = func(66,'a',3.14); //等价于func(66,'a',3.14);
tmp = func(,,3.14); //错误的,只能省略尾部的实参
默认实参声明:
函数的声明一般在头文件中,并且一个函数一般只声明一次,但多次声明也是可以的。
不过,在给定的作用域中一个实参只能被赋予一次默认实参。函数的后续声明只能只能为之前
那些没有默认值的形参添加默认实参,而且该形参右侧的所有形参必须都有默认值。
int func(a, b, c=3.14);
int func(a, b, c=1.33); //错误的,已被赋值过的默认实参,不能再次赋值
int func(a=10, b, c=3.14); //错误的,形参右侧的所有形参必须都有默认值
int func(a=10, b='v', c=3.14); //对的
默认实参初始值:
局部变量不能作为默认实参,除此之外,只要表达式的类型能转换成形参所需的类型,
该表达式就能作为默认实参。
int a = 10;
double b = 3.14;
char c = 'c';
int func(int x=a,double y=b,char z=c){} //全局变量初始化形参
void f()
{
a = 20; //改变了全局变量的值
double b = 5.32; //定义了一个新的局部变量
int tmp = func(); //等于func(20,3.14,'c'),f函数中的局部变量b不能作为默认实参
}