const可以放在成员方法的三个地方,前、中、后。
首先考虑在中间:
1、const修饰形参,表示形参是否为const
2、如果const修饰引用(指针指向的对象),可以进行过载,如果不是修饰引用(指针指向的对象),不能进行过载。为什么?
首先考虑引用,引用是一个对象的别名,在调用的时候,编译器根据原对象的常量性,可以找到一个最匹配的方法。const修饰指针指向的对象,和引用是同样的道理。如果const不是修饰引用或者指针指向的对象,就不能过载。因为,这种情况下,是整体拷贝,拷贝后的对象和原对象没有了任何关系。指针本身的常量性,不能过载,也是同样道理。
3、考虑下面的情况,有方法 void SetAge(int& a); void SetAge(const int& a);
int a;
const int ca;
p.SetAge(a); // 调用void SetAge(int& a);
p.SetAge(ca); // 调用void SetAge(const int& a);
因为编译器,是最优匹配。
a、考虑,如果没有non-const方法的声明和实现,出现什么问题?
没有问题,因为编译器,找不到最优匹配,就会看看有没有可以凑合使用的。const方法还是可以用的,因为在传递对象的时候,可以缩小操作对象的权力,但是不能放大权力。
b、如果没有const方法的声明和实现,出现什么问题?
编译出错,传递对象的时候,不能放大权力。也就是说,不能把const对象传递引用给non-const对象。
c、如果只是,去掉non-const方法的实现,出现什么问题?
出现“无法解析的外部命令”,为什么?编译器编译的时候,找到了最优匹配,但是在连接的时候,却找不到实现,这个时候,是不会再重头,去找凑合使用的方法。这也说明了,过载是编译十多态。
const在后面
1、const在后面,表示常量成员方法,不修改对象的内容。
2、const是否在方法后面可以进行过载,为什么?
在成员方法中,this指针是const指针,不能修改this的指向。为什么不能修改呢?不是办不到。而是因为,考虑下面的情况,我在对象p上调用方法,在方法内部修改了this指向,再去操作,这个时候是修改新指向的对象,而不是原来的对象p,这明显与程序猿的期望不一致。
而const成员方法中,this指针是指向const对象的const指针。由于编译器是最优匹配,在调用方法的时候,编译器能够根据方法拥有者的常量性,决定const成员方法或non-const成员方法哪个最匹配。
也就是说,能不能过载的关键是,站在编译器的角度考虑,在调用方法的时候,能不能确定最优匹配。如果两个是同样程度的匹配,是不行的。
const在前面
1、const在前面,表示返回对象的常量性,这个是不能进行过载的。为啥?
因为有些时候调用方法,是不关心返回值的。两个方法完全一样,指向返回值不一样,在调用的时候,没有处理返回值,编译器是没有办法知道你是调用那个方法。
2、考虑下面的需求,根据方法拥有者的常量性,过载两个方法,一个返回const,一个返回non-const,怎么办?
上面讲了,不能通过返回对象的常量性过载。那么,我们可以在方法后面加上const。