函数重载
同一作用域内,函数名相同但是形参列表不同的函数,为重载函数
下面两个函数就是重载函数,编译时会根据形参列表将这两个函数编译成不同的函数,在调用时传入对应的参数就可以调用不同的重载函数
void overloadfunc(int a[10], int len);void overloadfunc(int *s, int *e);int main(int argc, char const *argv[]){int a[6]={10,9,7};overloadfunc(a,5);overloadfunc(a, a+sizeof(a)/sizeof(int));return 0;}void overloadfunc(int a[], int len){cout<<"overloadfunc(int a[], int len)"<<endl;}void overloadfunc(int *s, int *e){cout<<"overloadfunc(int *s, int *e)"<<endl;}
注意:如果两个函数的函数名相同,形参列表也相同,只是返回值不同,那么在调用该函数时会报错
void overloadfunc(int *s, int *e);int overloadfunc(int *s, int *e);
所以函数是否重载与返回值无关,两个函数除了返回值不同,其余均相同时,编译时会报二义性错误
函数重载与const
拥有修饰形参本身的const的形参无法和一个没有const修饰的形参区分出来
int main(int argc, char const *argv[]){int a=7;overloadfunc(a);return 0;}void overloadfunc(int c){cout<<"overloadfunc(int c)"<<endl;}void overloadfunc(const int c){cout<<"overloadfunc(const int c)"<<endl;}
当编译上述代码时,会提示函数重定义,因为当把a传入overloadfunc时,既能匹配void overloadfunc(int c),也能匹配void overloadfunc(const int c),因为const int和int都能用一个常量字面值初始化
编译器不知道要调用哪个函数,所以将这两个函数视为同一个,报重定义错误
如果const修饰的是形参所指向或者绑定的对象,而不是形参本身,那么就可以将重载函数区分出来
int main(int argc, char const *argv[]){int a=7;overloadfunc(a);overloadfunc(7);return 0;}void overloadfunc(int &c){cout<<"overloadfunc(int &c)"<<endl;}void overloadfunc(const int &c){cout<<"overloadfunc(const int &c)"<<endl;}
调用overloadfunc(a)时,会有限匹配overloadfunc(int &c),当传入一个常量值时,只有overloadfunc(const int &c)能接受该实参,所以匹配overloadfunc(const int &c)
所以,当const修饰的是形参所指向或绑定的对象,而不是形参本身时,将生成两个不同的函数
不要滥用重载函数
void overloadfunc(int c){}void overloadfunc(const int &c){}void overloadfunc(int &){}int main(int argc, char const *argv[]){int a=7;overloadfunc(a);return 0;}
上述代码定义的三个重载函数并且在主函数中调用重载函数overloadfunc,但是编译器无法判断到底要调用哪个重载函数(因为三个函数都可以接受a作为函数的实参),所以报函数歧义错误
默认实参
函数在声明或定义时,对函数的形参进行值初始化,而在调用时,可以对该形参重新初始化,也可以忽略对该形参初始化
void defaultpara(int a,int b=10);void defaultpara(string str=" ");int main(int argc, char const *argv[]){defaultpara(10);defaultpara(10,20);defaultpara();defaultpara("123");return 0;}void defaultpara(int a, int b){cout<<"defaultpara(int a, int b)"<<endl;}void defaultpara(string str){cout<<"defaultpara(string str)"<<endl;}
调用函数时,如果想使用默认实参,就直接忽略对形参的初始化,否则,传入新的实参即可
默认实参只能在函数声明或者定义时进行添加,二者选其一,否则报错
内联函数
内联函数主要修饰用在短小,实现简单的函数,用inline修饰该函数
inline void defaultpara(string str=" ");
内联函数在调用点直接将函数展开,减少函数调用的次数和开销,从而让程序速度更快,所有在类的内部定义实现的函数都是内联函数
参考:
《C++ Primer》
欢迎大家评论交流,作者水平有限,如有错误,欢迎指出