2

我正在编写一个游戏引擎类,有人建议我添加这个#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
    }
}

这些方法有什么优点和缺点,首选的方法是什么?

4

2 回答 2

0

您似乎有一个与基类 (CBaseApi) 同名的 typedef。那不会好过的。

你的意思是这样的:

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
于 2013-08-04T23:24:34.813 回答
-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(); }
};

还有,C类?哎呀。你需要找到新的学习材料,伙计。

于 2013-08-04T23:26:54.077 回答