我们知道在用const修饰的类成员函数,这意味着什么,从effective c++这本书上我们可以了解到,这里存在两个流行的概念:bitwise constness(or physical constness)和logical constness.
bitwise const阵营的人相信,成员函数只有在不更改对象任何成员变量(static变量除外)时才可以说是const.也就是说它不能更改对象内的任何一个bit.然而我们不难发现有些例子能够通过bitwise
测试却存在潜在的改变成员变量的危险,比如说:
class String{
public:
String(char* pstring):pstring_(pstring){
}
char& operator[](int index)const{
...
return pstring_[index];
}
private:
char* pstring_;
};
客户可以写下如下代码:
const String str("any man of mine!");
char& c=str[0]; //call const-function
c='B'; //modified 'pstring_ ' from outer
这样写很显然不符合const的基本出发点(不能改变对象的属性),但是operator[]是通过bitwise测试的,编译器是能通过的,但不是我们想要的理想目标.
这种情况下就导出了logical constness,这一派主张一个const成员函数可以修改它所处理对象的某些位,但只有在客户端侦测不出来的时候才应如此.这种主张就导致了关键字mutable的诞生,它的作用是const函数实现体内可以修改由关键字mutable修饰的成员变量.比如我们修改一下前面一段代码:
class String{
public:
String(char* pstring):pstring_(pstring){
}
char& operator[](int index)const{
...
return pstring_[index];
}
//add new function to get the length of string
int getLength()const{
if(!isValidLength_){
stringLength_ = strlen(pstring_);
isValidLength_ = true;
}
return isValidLength_;
}
private:
char* pstring_;
mutable bool isValidLength_;
mutable int stringLength_;
};
这里新增的函数getLength虽然有const修饰,但是实现体中我们修改了关键字mutable修饰的成员变量,编译器是容许我们这么做的,因为它符合logical constness主张,呵呵,好了,现在对mutable了解
了吧?
请记住:
■ mutable修饰的类成员变量的值可以在同一个类的const成员函数中被修改.