class X
{
public:
X():buffer_(0),isComputed_(false){}
//...
void setBuffer()
{
int *tmp = new int[MAX];
delete []buffer_;
buffer_=tmp;
}
void modifyBuffer(int index,int value) const //不道德!
{
buffer_[index] = value;
}
int getValue() const
{
if(! isComputed)
{
computedValue_ = expensiveOperation();//错误!
isComputed_ = true;//错误!
}
return computedValue_;
}
private:
static int expensiveOperation();
int *buffer_;
bool isComputed_;
int computedValue;
};
1、modifyBuffer可以被合法地标记为常量,因为它没有修改X对象,它只是修改X的buffer_成员所指向的一些数据。
这种做法是合法的,但很不道德。
2、getValue被标记为const ,但是改变了X对象,显然是错误的。
对getVlue的有两种修改,一下作对比
想法一:
int getValue() const
{
if(!isComputed_)
{
X *const aThis = const_cast<X *const>(this);//糟糕的念头!
aThis->computedValue_ = expensiveOperation();
aThis->isComputed_ = true;
}
return computedValue_;
}
评价:const 成员函数中不能对成员变量修改是因为this指针为const X * const this(非const成员函数this 指针为X * const this),
所以有“X *const aThis = const_cast<X *const>(this);”这一步的想法。千万要抵制这种错误的诱惑!
想法二:
将有关数据成员声明为mutable。问题轻松解决!