3

ここでミュータブルの使用が適切かどうかお尋ねしたいと思います。

#include <iostream>

class Base
{
protected:
  int x;

public:
  virtual void NoMod() const
  {
    std::cout << x << std::endl;
  }
  void Draw() const
  {
    this->NoMod();  
  }
};

class Derive : public Base
{
private:
  mutable int y;

public:
  void NoMod() const
  {
    y = 5;
  }
};

int main()
{
  Derive derive;

  // Test virtual with derive
  derive.Draw();

  return 0;
}

Base クラスはサードパーティのライブラリです。私はそれを拡張して、独自の NoMod() を提供しています。ライブラリ独自の NoMod() を const として宣言しています。

私の NoMod() は、独自のメンバー変数を変更する必要があるという点で Base とは異なります。

したがって、自分の NoMod() をコンパイルして、Draw() が呼び出されたときに呼び出されるようにするには、

1) Derive::NoMod() を const として実装し
ます。 2) int y を変更可能にします。

これは私ができる最善のことですか?

4

7 に答える 7

10

何を参照しているか、またはどのように使用されているかについてのコンテキストを提供しないため、言うのは難しいy.

一般に、mutable変更可能な変数を変更してもオブジェクトの実際の「値」が変更されない場合にのみ適切です。たとえば、C スタイルの文字列のラッパーを作成していたとき、mLength要求されたものがオブジェクトであっても、長さをキャッシュできるように、内部変数を変更可能にする必要がありましたconst。長さや文字列は変わらず、クラスの外からは見えないので、作って大丈夫mutableでした。

于 2009-04-15T00:41:26.137 に答える
3

mutableオブジェクトの状態の実際の一部ではない参照カウントなどの場合にのみ、問題ないと思います。

オブジェクトy物理的状態の一部であるが、論理的状態ではない場合、これは問題ありませんが、そうでない場合は実行しないでください。

于 2009-04-15T00:34:38.133 に答える
1

The only situations where I needed the mutable feature are:

  • a cached version of derived data. For example, if you have a Rectangle class that has a GetSurface() member function that is likely to be called a lot, you could add a mutable m_surfaceCache member variable to keep the derived data.
  • a critical section member variable. This is because my CriticalSection::Enter() function is conceptually not const, but the critical section member variable is not a real part of the class data, it is more like a compiler guideline.

However, as a general rule of thumb, I'dd advise not to use mutable too often, as it bypasses C++'s wonderful const feature.

于 2009-04-15T09:17:28.690 に答える
1

あなたが言ったように、それがサードパーティのライブラリの一部である場合、選択の余地がないかもしれません. C++ は本質的に実用的な言語であり、常に「ベスト プラクティス」とは限らない場合でも、必要なことを実行できます。

ただし、注意すべきことの 1 つは、サード パーティのライブラリが、その const 指定子を追加して NoMod がオブジェクトを変更してはならないことを文書化していることです。その契約に違反することにより、あなたは自分自身を潜在的なトラブルにさらすことになります. 場合によっては、ライブラリが NoMod を複数回呼び出す場合、派生クラスはそれをより適切に処理できます。これは、真の const メソッドには問題がないためです。

最初に問題を解決する別の方法を探しますが、そこで失敗すると可変であると宣言します。

于 2009-04-16T05:26:04.867 に答える
1

「変更可能」と考えることができる別の状況は、「const」メンバー変数を持つクラスがあり、「const」メンバーの代入をスキップせずに代入演算子 (=) を実装する必要がある場合です。

また、最初に宣言された 'const' 変数に const_cast が適用され、それを使用することは C++ 標準に従って UB です。したがって、メソッドのインターフェースが内部的に変更する必要がある「const」を受け入れる場合は、それに「mutable」引数を渡します。

上記の状況から同じことが適切かどうかを判断することができます。つまり、意味的に意味があるのはそれだけです! ソースコードをコンパイル可能にするために使用しないでください。

よろしく、

于 2009-04-15T05:29:08.880 に答える