4

クラスがあるとしましょう:

class NumberCollection
{
public:
    typedef std::set<int> SetType;
    typedef SetType::iterator iterator;
    void insert(int n);

    iterator begin();
    iterator end();
    size_t size() const;

    iterator difficultBegin();
    iterator difficultEnd();
    size_t difficultSize() const;    

private:
    SetType easySet_, difficultSet_;
}

insert()に要素を追加する場所easySet_difficultSet_のメンバーは のメンバーによって変わりeasySet_ます。

私が抱えている問題は、複数の挿入difficultSet_が常に再計算されることを意味することです。difficultSet_そのため、遅延計算を行いたい(つまり、 difficultBegin()difficultEnd()、またはdifficultSize()が呼び出された場合のみ)。問題は、それ以外の場合は操作できないため、実際に作成する必要があることですdifficultSet_mutabledifficultSize()

だから今、私のクラス宣言は次のようになります

class NumberCollection
{
public:
    typedef std::set<int> SetType;
    typedef SetType::iterator iterator;
    void insert(int n);

    iterator begin();
    iterator end();
    size_t size() const;

    iterator difficultBegin();
    iterator difficultEnd();
    size_t difficultSize() const;    

private:
    SetType easySet_; 
    mutable SetType difficultSet_;
    mutable bool upToDate_;
}

ただ、これはデザインが悪い気がします。より良い方法はありますか?

4

4 に答える 4

12

それは完全にそれを行う方法です。const はバイナリ const を意味することも、概念的に const を意味することもあります。mutable を使用するということは、後者を実行していることを意味します。これは問題ありません。

于 2009-05-19T05:49:45.863 に答える
4

mutable を使用する理由を理解するために、他のオプションを調べることができます。

const_castを使用して同じ問題を解決できます。

size_t NumberCollection::difficultSize() const
{
     if(!upToDate_)
     {
          NumberCollection& nonConst = const_cast<NumberCollection&>(*this);
          nonConst.difficultSet_ = PerformExpensiveCalculationFunction();
          nonConst.upToDate_ = true;
     }
     // etc....
}

このソリューションを提供したので、 mutableを使用するよりも劣っていると言えます。メンバーがmutableとしてマークされている場合、ヘッダーを見るだけで、あなたがそれをどのように扱っているかを知ることができます。const_castを使用すると、この情報を取得できません。

しかし、誰かが議論の反対側を取り、ヘッダーで実装の詳細を公開しないほうがよいと言うかもしれません。

于 2009-05-19T06:12:38.440 に答える
3

これが本質的に、C++ に可変構造がある理由です。ミュータブルの誤用に関するAlan De Smet の暴言は、ミュータブルが使用されるべきではない状況の種類を示しています。

この場合、hardSize() は NumberCollection が表すものを変更しません。これは const としてマークするのに適しています。場合によっては内部を変更する必要があります。

于 2009-05-19T05:55:33.673 に答える
1

あなたのソリューションは C++98 で問題ありません。C++11 では、変更可能なデータへのアクセスを同期することを検討する必要があることに注意してください。そうしないと、すべての const メンバー関数がスレッドセーフであると想定する STL によってクラスが使用されるときに問題が発生する可能性があります。

詳細については、「const は C++11 でスレッドセーフであることを意味しますか?」を参照してください。

于 2013-01-04T00:08:35.987 に答える