首先,我们知道: 每个成员函数都有一个额外的、隐含的形参this。在调用成员函数时,形参this初始化为调用函数的对象的地址。成员函数的函数体可以显示的使用this,但是不是必须这样做。在普通的非const成员函数中,this的类型是一指向类类型的const指针,可以改变this所指向的值,但是不能改变this所保存的地址。
在这种情况下,我们引入了const成员函数,它的作用是:改变了this形参的类型。this指针变成了一个指向const类类型对象的const指针。它既不能改变this所指向的对象,也不能改变this所保存的地址。
那我们加入const的目的是什么呢?这样做有什么好处呢?
我们知道,类的成员函数,一些改变对象,另一些不改变对象,对于不改变对象的那些,我们就在函数后面加上const声明。
例如:假设num为class point的私有成员
int point::GetValue (){
return num;
}
该函数的作用只是返回num的值,并未改变对象的值。因此,我们可以在函数后面加上const(若在前面加上,表示返回值为const类型).
而有些函数,则改变了对象的值,例如:
int point::Setvalue(int &m){
num=m;
}
那么声明为const就是错误的。
我们为了看起来更舒服,看下面的代码:
class point{
public:
int Getvalue() const
{
return num;
}
int Setvalue(int &m)
{
num=m;
}
private:
int num;
};
需要注意的是,const成员函数需要在函数声明和函数定义时都声明const(对于类外定义的函数来讲).
非常量成员函数不能被常量对象调用:
const point p;
p.getvalue();//ok
p.setvalue(2);//error
但是构造函数和析构函数除外,因为他们从不定义为const函数,但是可以被const对象所调用,
总结一句:const对象,指向const对象的指针和引用只能用于调用其const成员,如果尝试调用非const成员,则是错误的,而非const对象则可以调用任意成员,当然非const成员最佳。
什么情况都有例外——看下面这段程序:
class point{
public:
int setvalue(int &m) const
{
num=m;
}
private:
mutable int num;
};
也声明为const函数,但是我们却改变了对象的值,原因就是我们在num前加了mutable表示num为可变数据成员,在此情况下,任意成员函数,包括const成员函数,都可以改变num的值。