void *作为未知变量类型

时间:2009-02-28 03:17:23

标签: c++ void

我目前正在使用C ++中的sprite引擎。我有一个带有虚函数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 个答案:

答案 0 :(得分:1)

这是继承层次结构中参数类型变化的一个相对常见的问题;你的子类想要从父类中专门化'api_params'的类型。

我认为这样可以,但它就像C一样。我认为更好的解决方案是使init_api非虚拟,并在子类中使用正确的类型实现它。无论如何,D3DPRESENT_PARAMETERS结构很可能只​​对DirectX引擎有意义,所以为什么不在逻辑上属于它的子类中呢?

答案 1 :(得分: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;
  }
};

但是,使用符合宏观计划的东西。

答案 2 :(得分:1)

另一种方法是为每个实现提供一个公共头和不同的* .cpp文件。这样,您可以只包含D3D或仅包含项目中的OGL文件。 IMO最好在编译时选择API,这样就不会链接到两个库。

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

这种方法的另一个好处是你不需要支付你不需要的虚拟功能,虽然我意识到虚拟通话的成本非常小。

答案 3 :(得分:0)

我真的不喜欢这个API。为什么要使用void指针?为什么不将第一个参数作为指针或引用D3DPRESENT_PARAMETERS?你知道这应该是正确的吗?这种类型更安全。