2

我目前正在使用 C++ 开发精灵引擎。我有一个带有虚函数 init_api 的抽象类 IEngine。这需要一个 void*。

    //  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,这样您就不会链接两个库。

至于void*,我不是很喜欢。我认为您最好定义自己的类型,然后使用包装器结构/类和 typedef 将它们映射到 API 类型。您可以转发声明这些,并将实际实现放在您的 *.cpp 文件中。

这种方法的另一个好处是您无需为不需要的虚拟功能付费,尽管我意识到虚拟调用的成本非常小。

于 2009-02-28T07:45:19.887 回答
0

我真的不喜欢这个 API。为什么使用空指针?为什么不将第一个参数设为指针或引用D3DPRESENT_PARAMETERS?你知道无论如何它应该是这样的吗?这是更类型安全的。

于 2009-02-28T03:22:03.607 回答