回顾一下this指针,在类X的非常量成员函数中,this指针的类型为X * const。这里的this指针是指向非常量X的常量指针。由于this指向的对象不是常量,因此它可以被修改。而在类X的常量成员函数中,this的类型为const X * const。这是一个指向常量X的常量指针。因为指向的是常量,所以不能被修改,这也是常量成员函数和非常量成员函数之间功能上存在差异的原因(常量成员函数不可以改变成员变量的值,非常量成员函数随意)。
class X
{
public:
X():prt(0),a(10),b(20){}
void setA()//可以修改a的值
{
a=2;
}
void setB()const//不可以修改b的值
{
b=2;
}
//不推荐以下写法,虽然他正确运行,稍后介绍更好的方法
void setPtr(int value)const//可以修改ptr指向的变量的值,不会报错
{//ptr是成员变量,它也是一个指针,它的值一直没变(它一直指向了一个变量)
*ptr=value;//但我们可以通过ptr来间接修改它指向的变量的值
}//这时的const成员函数只是限制了成员变量本身的值不能在这里改变
private:
int a;
int b;
int *ptr;
};
int main()
{
X m;
m.setB();
m.setC(2);
return 0;
}
编译结果为:
只有在通过对象m调用setB()时报错,原因为被const修饰的成员函数是不被允许修改成员变量的,但却可以修改指针指向的变量的值(间接修改一些东西),这种用法一般不推荐,当我们希望在被const修饰的成员函数中修改我们的成员变量时,可以事先将成员变量声明为mutable,如
class X
{
public:
X():prt(0),a(10),b(20){}
void setA()//可以修改a的值
{
a=2;
}
void setB()const//可以修改被mutable修饰的b的值
{
b=2;
}
void setPtr(int value)const//可以修改ptr指向的变量的值
{
*ptr=value;
}
private:
int a;
mutable int b;
int *ptr;
};
int main()
{
X m;
m.setB();//没有报错
m.setC(2);
return 0;
}
运行成功