前言
在函数重载时,对于const形参十分迷惑,经过查阅资料和思考之后得到如下结论。
一、如果形参是普通对象
普通对象的意思是非引用和指针对象,当是普通对象时,在形参前面加const编译器会报错;
因为在调用的时候,使用f(10),那么10是一个字面值常量,但是此字面值常量因为是值传递所以完全可以直接传递给f(int i)中且是完美匹配,而不需要专门定义一个f(const int i)函数。
int f(int i) {}
int f(const int i) {} //报错,重复定义
二、如果形参是引用
如果是引用,因为引用本身就具备顶层const,所以并不会因为底层const的问题而导致不能重载,至于底层const不能重载在指针中进行介绍;
当在调用fun函数的时候,完全可以通过传入的具备不具备const属性而判断是选择哪个fun函数,所以完全可以重载。
void fun(double &i) {}
void fun(const double &i) {}
三、如果形参是指针
当是指针时,就必须分两种类型来讨论,第一种是形参为指向常量的指针,第二种是常量指针也有叫指针常量的;
1.形参为指向常量的指针
当形参为指向常量的指针时,因为指向常量,所以指针还是正常指针,还可以指向其他地方。同加const的引用一样,也可以通过传入的实参是否具备const属性而判断使用哪个fun函数。
void f(int *i)
{
cout << "f(int *i)" << endl;
}
void f(const int *i)
{
cout << "f(const int *i)" << endl;
}
2.形参为常量指针
常量指针,这个叫法是参考值C++ Primer中也称之为顶层const,当定义了一个常量指针之后,这个指针本身就变成了一个常量,必须初始化,而且无法改变指向。
定义的方式为int *const exp=&k;因为是常量指针,是可以接受普通非常量对象,那么问题来了,当我传递一个普通非常量对象时,程序是无法分辨是传递给哪一个fun,所以形参为常量指针时,无法重载。
void f(int *i)
{
cout << "f(int *i)" << endl;
}
void f(int* const i)
{
cout << "f(int* const i)" << endl; //报错
}
总结
而针对const和非const的对象类型,透过原理解释和理解可能比较困难,在初期通过对象的特性进行记忆和理解,能够更快的记忆和运用。