2

私は現在、C++のスプライトエンジンに取り組んでいます。仮想関数init_apiを持つ抽象クラスIEngineがあります。これはボイド*を取ります。

    //  Initialise the engines' API
//  api_params - void* to api parameters for initalisation
//  hWnd - window handle
virtual bool init_api( void* api_params, HWND hWnd ) = 0;

次に、DirectXで実装されたエンジンクラスCEngineDXがあります。次に、api_paramsをD3DPRESENT_PARAMETERS *にキャストするため、DirectXの初期化に使用できます。

//  Cast api_params to a D3DPRESENT_PARAMETERS
D3DPRESENT_PARAMETERS* presentParams = NULL;
presentParams = reinterpret_cast< D3DPRESENT_PARAMETERS* >( api_params );

私はこの設定に非常に満足していますが、必要に応じて、他のプログラマーにこの「ソリューション」を見てもらいたいと思っていました。

返信に乾杯!

カール

4

4 に答える 4

1

これは、継承階層の引数タイプのバリエーションに関する比較的一般的な問題です。サブクラスは、親クラスの「api_params」のタイプを特殊化する必要があります。

これでいいと思いますが、Cっぽいです。init_apiより良い解決策は、非仮想化して、サブクラスに正しい型で実装することだと思います。とにかく、おそらくD3DPRESENT_PARAMETERS構造体はDirectXエンジンでのみ意味があるので、論理的に属するサブクラスに構造体を入れてみませんか?

于 2009-02-28T03:21:49.240 に答える
1

テンプレートを使用することもできますが (キャストが嫌いですか)、その場合は階層を使用する必要があります。

template<class T>
struct Engine {
   bool init_api(const T& params, HWND hWnd);
};

//specialize for DirectX
template<>
struct Engine <D3DPRESENT_PARAMETERS> {
  bool init_api(const D3DPRESENT_PARAMETERS& params, HWND hWnd) {
    return true;
  }
};

ただし、物事の壮大な計画に適合するものを使用してください。

于 2009-02-28T07:32:59.433 に答える
1

それを行う別の方法は、実装ごとに共通のヘッダーと異なる *.cpp ファイルを用意することです。そうすることで、プロジェクトに D3D ファイルのみ、または OGL ファイルのみを含めることができます。IMO は、コンパイル時に API を選択することをお勧めします。そのため、両方のライブラリにリンクしないでください。

ボイド*に関しては、私はあまり好きではありません。独自の型を定義してから、ラッパー構造体/クラスおよび typedef を使用して API 型にマッピングする方がよいと思います。これらを前方宣言し、実際の実装を *.cpp ファイルに入れることができます。

この方法のもう 1 つの利点は、必要のない仮想関数にお金を払わないことですが、仮想呼び出しのコストがかなり小さいことはわかっています。

于 2009-02-28T07:45:19.887 に答える
0

私はこのAPIが本当に好きではありません。なぜvoidポインタを使用するのですか?最初のパラメータをポインタまたは参照にしないのはなぜD3DPRESENT_PARAMETERSですか?あなたはそれがとにかく正しいべきであるということを知っていますか?これはよりタイプセーフです。

于 2009-02-28T03:22:03.607 に答える