我目前正在使用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 );
我对这个设置很满意,但是如果你愿意的话,想让其他程序员查看这个“解决方案”。
欢呼回复!
卡尔
答案 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
?你知道这应该是正确的吗?这种类型更安全。