我正在编写一个游戏引擎类,我被建议添加这个#define以这种方式处理多个API:
#ifdef OGL
typedef COpenGl CBaseApi;
#elif defined( OGLES )
typedef COpenGlEs CBaseApi;
#elif defined( DX9 )
typedef CDirectX9 CBaseApi;
#elif defined( DX10 )
typedef CDirectX10 CBaseApi;
#elif defined( DX11 )
typedef CDirectX11 CBaseApi;
#endif
我有两个问题:如何才能使上述工作成功?
我试过了:
class CBaseAPI
{
//abstract class, virtual functions
}
class COpenGL : public CBaseAPI
{
//implementations
}
但它并没有像我预期的那样奏效。
第二个问题是,这种#define方法比使用某种工厂更好吗?我最初是这样做的:
//inside the Main program
myGameEngine.Initialize(GraphicAPI::DirectX11);
//inside the Initialize function
void GameEngine::Initialize(GraphicAPI graphicAPI)
{
switch(graphicAPI)
{
case GraphicAPI::DirectX11:
{
//Defined as private members:
//BaseAPI graphicAPI;
//class CDirectX11 : public BaseAPI
graphicAPI = new CDirectX11();
}
//other cases here
}
}
这些方法有什么优点和缺点,首选方法是什么?
答案 0 :(得分:0)
您似乎有一个与基类同名的typedef(CBaseApi)。这不会很好。
你的意思是:
class CBaseAPI
{
//abstract class, virtual functions
};
class COpenGlEs : public CBaseAPI
{
// implementations
};
#ifdef OGL
typedef COpenGl BaseApiImpl;
#elif defined( OGLES )
typedef COpenGlEs BaseApiImpl;
#elif defined( DX9 )
typedef CDirectX9 BaseApiImpl;
#elif defined( DX10 )
typedef CDirectX10 BaseApiImpl;
#elif defined( DX11 )
typedef CDirectX11 BaseApiImpl;
#endif
答案 1 :(得分:-1)
第二个是可怕的。两阶段初始化非常容易出错,在一般情况下,您的游戏绝对不需要在运行时更改渲染API。使用接口和继承完全浪费时间和性能,更不用说丢失了很好的强类型。
对于#define,不需要通过继承链接类。使用模板可能会做得更好,但条件编译是预处理器的用途。简单的使用场景:
class OGL {
public:
void dostuff();
};
class DX {
public:
void dostuff();
};
class GameEngine {
#ifdef USE_OPENGL
OGL BaseAPI;
#else
DX BaseAPI;
#endif
public:
void dostuff() { BaseAPI.dostuff(); }
};
另外,CClass? Owch。你需要找到新的学习材料,伙计。