何为常量函数
1.this指针
当我们调用成员函数时,实际上是在替某个对象调用它。成员函数通过一个名为this指针的隐式参数来访问它调用的对象的地址,这样在成员函数内部,我们就可以使用this来访问类内成员。那么由于this始终指向这个地址,所以它是一个常量指针,不允许改变它所保存的对象地址。但是this对应的是指向类类型的非常量版本的常量指针,我们知道,这样的指针是不能绑定到一个常量对象上的。具体看下面的例子:
class people{
public:
people(){}
people(int x):score(x){}
~people(){}
int getScore(){return score;}
private:
int score;
};
int main(){
const people p1(22);//常量
cout << p1.getScore() << endl; //error,不能用常量绑定非常量指针
return 0;
}
这段代码在编译器中是无法编译通过的。我们知道用指向常量的指针来绑定常量和非常量都是可以的,那么为了提高成员函数的灵活性,我们就可以将这个this指针定义为指向常量的指针(同时其本身就是常量指针)。方法就是在成员函数的参数列表后面加入关键字const,则上述getScore函数修改为:
int getScore() const {return score;}
这样上述代码的main函数就可以正常运行了。
2.补充
对于成员函数,其有一个隐式参数,来表示对象的地址,例如:
class Foo{
public:
void hello(int a){
cout << "hello" + a << endl;
}
//等价于
//void hello(Foo* const this, int a){
//out << "hello" + a << endl;
//}
};
int main(){
Foo foo;
int a = 2;
foo.hello(a);
//等价于
foo.hello(&foo, a);
}
上面的代码展示了对象地址的隐式参数传递,当我们将hello设置为常量函数后,就可以理解为其等价版本变为:
void hello(const Foo* const this, int a){
out << "hello" + a << endl;
}
3.常量成员函数的重载
两个成员函数,名字和参数列表都一样,但是一个是常量函数一个不是,则也算重载。
class people{
public:
people(){}
people(int x):score(x){}
~people(){}
int getScore() {return score;}
int getScore() const {return score};
private:
int score;
};
int main(){
const people p1(22);//常量对象
people p2(23); //非常量对象
cout << p1.getScore() << p2.getScore() << endl; //重载
return 0;
}