0

すべて共通の基本クラスから派生した一連のクラスがあります。これらのクラスを多態的に使用したい。インターフェイスは、戻り値が特定の派生クラス全体で一定であるが、派生クラスごとに異なる getter メソッドのセットを定義します。例えば:

enum AVal
{
  A_VAL_ONE,
  A_VAL_TWO,
  A_VAL_THREE
};

enum BVal
{
  B_VAL_ONE,
  B_VAL_TWO,
  B_VAL_THREE
};

class Base
{
  //...
  virtual AVal getAVal() const = 0;
  virtual BVal getBVal() const = 0;
  //...
};

class One : public Base
{
  //...
  AVal getAVal() const { return A_VAL_ONE };
  BVal getBVal() const { return B_VAL_ONE };
  //...
};

class Two : public Base
{
  //...
  AVal getAVal() const { return A_VAL_TWO };
  BVal getBVal() const { return B_VAL_TWO };
  //...
};

これは物事を行う一般的な方法ですか?パフォーマンスが重要な考慮事項である場合、属性を外部構造に引き出したほうがよいでしょうか。たとえば、次のようになります。

struct Vals
{
  AVal a_val;
  VBal b_val;
};

各インスタンスにa を格納し、次のようVals*に書き換えBaseますか?

class Base
{
  //...
  public:
    AVal getAVal() const { return _vals->a_val; };
    BVal getBVal() const { return _vals->b_val; };
  //...
  private:
    Vals* _vals;
};

追加の逆参照は、本質的に vtable ルックアップと同じですか? この種の状況の確立されたイディオムは何ですか? これらのソリューションは両方ともばかげていますか? どんな洞察も大歓迎です

4

4 に答える 4

1

最初の方法はより明確に見え、それらの方法をオーバーライドするように強制します(とにかく最初の子で)。仮想呼び出しのオーバーヘッドは、予想よりも少なくなる傾向があると思います。コードのプロファイルを作成し、仮想呼び出しにかなりの時間がかかる場合にのみ、2番目のアプローチのように最適化を試みます。

そうは言っても、あなたはどのような問題を解決しようとしていますか?このようなクラスIDが役立つ場合もありますが、そのようなインターフェイスがまったくなくても、別のインターフェイス抽象化で同じことを実行できる場合もあります。

于 2010-06-08T17:44:47.037 に答える
1

個人的には、派生した特定の情報をすべて含む構造体 (への参照) を返す GetTypeStats() のようなもの、または D3D で見られるような QueryInterface を実装します。このシナリオでは、静的ポリモーフィズムも考慮する必要があります。ただし、クラスがランタイム ポリモーフィックでなければならない場合、仮想関数呼び出しを排除するために実際にできることは何もありません。

于 2010-06-08T17:46:20.370 に答える
0

異なるのが値だけで、コンパイル時に修正される場合は、それらをテンプレート引数にすることができます。

template< AVal aval, BVal bval>
class Derived : public Base
{
  AVal getAVal() const { return aval };
  BVal getBVal() const { return bval };
};

typedef Derived<A_VAL_ONE, B_VAL_ONE> One;
typedef Derived<A_VAL_TWO, B_VAL_TWO> Two;
于 2010-06-08T18:20:04.190 に答える
0

dynamic_castこれは、プログラマーが。の使用を避けたい場合に、ポリモーフィック型に対して貧乏人を行う一般的な方法ですdynamic_cast。そのような場合、これはマイクロ最適化です。すべてのマイクロ最適化と同様に、先に進む前に、必要に応じて適切な判断を行う必要があります。プロファイラーが、これを実行してもパフォーマンスが向上しないと言った場合はdynamic_cast、を使用する方がはるかに良いでしょうdynamic_cast

于 2010-06-08T18:21:47.400 に答える