0

Unity3dにあるものと同様の「コンポーネントマネージャー」クラスをC++で作成しようとしています。私が欲しいのは、BaseComponentなどのクラスの派生型を保持できるコンテナクラスです。団結して、ジェネリックスを使用してタイプセーフな方法でコンポーネントを要求できます。

タイプがDerivedComponentType&であるmanager.GetComponent()

C++でも同じインターフェースが欲しいのですが。このように、コンポーネントがAddComponent関数を介して追加される限り、プロセス全体が使用法の観点からタイプセーフであることが保証されます。

私はここで、文字列で識別するなどのことを避けるようにしています。すべての派生型に同じ名前の静的メンバー関数を指定し、そのアドレスをクラスインスタンスへのマップインデックスとして使用することでも、これを実行できることに気付きました。コンポーネントマネージャーのユーザーが、独自のコンポーネントを派生させることを選択した場合に、この関数が存在することを確認する必要がないように、これは行いたくありません。

ありがとう。

4

1 に答える 1

1

これを行う 1 つの方法は、dynamic_cast を使用することです。

template <typename Derived>
Derived* GetComponent (void)
{
  // componentlist is a std::vector<BaseClass*>
  for (unsigned i = 0; i < componentlist.size(); ++i)
  {
    Derived* val = dynamic_cast<Derived*>(componentlist[i]);
    if (val != 0)
      return val;
  }
  return 0;
}

型がテンプレートで指定されたものと一致しない場合、dynamic_cast は null ポインターを返します。もちろん、これは実行時に行わなければならないことです。最新のマシンでは、頻繁に実行しない限り、これは大きなヒットにはなりません。はるかに複雑な方法が他にもいくつかあります。

型情報を見つけるためのより高速な方法を提供するリフレクション システムを作成することも検討できます。これにより、次のようになります。

Derived* GetComponent (MetaData *TypeIWant)
{
  if (componentlist[i]->Type() == TypeIWant)
  //...
}

これは長期的にははるかに多くの作業を必要とし、あなたの側でいくつかの調査を行う必要がありますが、文字列ルックアップと「恐ろしい」dynamic_cast を非常に多く使用する必要がない、おそらく私が知っている唯一の c++ オプションです。人は嫌いになりがちです。

于 2012-05-17T02:42:35.730 に答える