C++の定数メンバー関数

1428 ワード

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には2つの修正がありますが、比較してみましょう.
アイデア1:
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(this);」この一歩の考え.このような誤った誘惑に抵抗しなければならない.
アイデア2:
関連データ・メンバーをmutableとして宣言します.問題は簡単に解決できます.