《C++ Primer(第5版)》Page208 重载和const形参 一节中有一下说明及代码:
一个拥有顶层const的形参无法和另一个没有顶层const的形参区分开来:
1.
Record lookup(Phone);
Record lookup(const Phone); //重复声明了Record lookup(Phone)
2.
Record lookup(Phone *);
Record lookup(Phone *const); //重复声明了Record lookup(Phone *)
如果形参是某种类型的指针或引用,则通过区分其指向的是常量对象还是非常量对象可以实现函数重载,此时的const是底层的:
3.
Record lookup(Account &); //函数作用于Account的引用
Record lookup(const Account &); //新函数,作用于常量引用
4.
Record lookup(Account *); //新函数,作用于指向Account的指针
Record lookup(const Account *); //新函数,作用于指向常量的指针
个人理解:
函数重载时形参加上const是否是重载,应该站在函数调用着的角度来看:
1. 情况1下,常量:
实参传入形参Phone后,调用者不管函数内部如何处理形参,因为函数返回时,实参的值不会有任何变化;
实参传入形参const Phone后,函数不允许修改形参的值,函数返回时,实参的值也不会有任何变化;
所以对于调用者来说,形参Phone和形参const Phone,没有任何区别,不属于重载。
2. 情况2下,指针常量:
形参Phone *拷贝实参指针的值(地址),函数并内部可能修改地址的值,但函数返回时,实参指针的值不会有任何变化;但指针地址存储的内容可以改变;
Phone *const表示形参指针的值即地址是常量不可修改,但指针地址存储的内容可以改变;
所以对于调用者来说,形参Phone *和形参Phone *const,是一样的效果,不属于重载。
3. 情况3下,引用:
形参Account &是实参的别名,函数内部可以修改其值,且函数返回时,实参值也会随之变化;
const Account &表示形参是实参的别名,但是不能修改其值,所以在函数返回时,实参值不可能发生改变;
所以对于调用者来说,形参Account &和形参const Account &,得到的结果可能不一样,属于函数重载。
4. 情况4下,常量指针:
形参Account *拷贝实参指针的值(地址),函数并内部可能修改地址的值,但函数返回时,实参指针的值不会有任何变化;但指针地址存储的内容可以改变;
const Account *表示形参指针地址存储的内容不可改变,虽然指针的值可变,但函数返回时,实参指针的值不会有任何变化;
所以对于调用者来说,形参Account *和形参const Account *,得到的结果可能不一样,属于函数重载。
这样理解的话,就可以不用记忆什么顶层底层const,纯靠记忆还容易记反。