2016-12-04 9 views
2

メンバ関数fを持つクラスAがあるとします。 fは、Aの何も変更せずに単純に値を計算します。しかし、実装では、それは一時的Aを変更しない:constメンバ関数のフィールドを一時的に変更する

class A 
{ 
    int f() const 
    { 
     tiny_change(b); // since copying "b" is expensive 
     int result = compute(b); 
     tiny_recover(b); // "b" backs to the original value 
     return result; 
    } 

    B b; 
} 

もちろん上記のコードはコンパイルされません。ここで私が知っている2つの回避策は次のとおりです。これらのソリューションの

  1. const_cast<A*>(this)->b
  2. mutable B b;

どれも完璧ではありません。解決策1は、Aのインスタンスがそれ自身constであるときにUBを伴う。他のconstのメンバー関数でコーダーが誤ってbを変更するのを防ぐことができないように、ソリューション2はクラス全体に変更可能性を公開します。

const_castは "ローカル"ですが、UBをトリガーする可能性があります。 mutableはメモリーに安全ですが、グローバルでもあります。

3番目の解決策がありますか、何か間違って理解していますか?

+0

'tiny_change(b)'の代わりに 'tiny_change(result)'を並べて、変更されていない 'B'の結果を計算できませんか? – Zereges

+0

"小さな変更"を取るために 'compute'をオーバーロードすることはできませんし、' b'の値の代わりにその値を使用できますか? 'B'は明らかにビット単位の論理的なものではなく、クラスの論理的な性質に関係しています。両方のソリューションはこの場合ハックです。 – StoryTeller

+0

@Zeregesこれらの関数は私のケースでは準同型ではありません – rolevax

答えて

2

一つの可能​​性は、それmutableを持つクラスでBをカプセル化することで、それは通常のconstである場合にのみ、それはA::fをbefriendsことを除いて、constのアクセスを可能にするでしょう。たとえば、次のようにしてください:

関連する問題