2007年9月6日星期四

mutable的使用方法

在C++中,很多关键字是我们平常不注意的。今天要提到的一个就是mutable。

mutable是个变量修饰符。它的作用是让这个变量在const成员函数中可以被修改。那const成员函数的语义本来就是防止成员变量被修改,为什么还要允许mutable来破坏这样的语义呢?

事实上,很多情况下面const是作为一个getter函数在使用。对于一个getter函数来说,他只要简单的返回要求的值就可以了。但是当这个值在已经被计算过,被赋过值的情况下,这个说法是成立的。但是在很多程序中,为了加快速度,对于不用的成员变量都采用了推迟计算。如果所有的值都放在类型初始化的时候,会大大减缓速度。这就是为什么很多设计者都会为一个类提供init()方法而不是把所有的初始化工作都放在构造函数里面的原因。

言归正传,有时候需要在getter函数里面在返回值之前先进行计算,这就要改变const函数内的内容了。这种时候,有些人就会这样写:

int get_value() const{
if( !isInited ){
Type* const pThis = const_cast(this);
pThis->value_ = 123;
}
return value_
}
千万不要这样用,这是“犯罪”。这种做法完全破坏了const成员函数的语义。
正确的做法就是使用motable。

class Type{
public:
//...
int get_value() const{
if( !isInited ){
Type* const pThis = const_cast(this);
pThis->value_ = 123;
}
return value_
}

private:
//...
mutable int value_;
};

这样的设计符合“把逻辑上,设计上来说应该是const的函数声明为const函数”