简体   繁体   English

在运行时或编译时更改API?

[英]Changing APIs in run-time or compile-time?

I'm coding a game engine class and I've been suggested to add this #define to deal with multiple APIs in this manner: 我正在编码一个游戏引擎类,建议我添加此#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

And I have two questions: How can I get the above to work? 我有两个问题:如何使以上内容起作用?

I tried: 我试过了:

class CBaseAPI
{
    //abstract class, virtual functions
} 
class COpenGL : public CBaseAPI
{
    //implementations
}

But it didn't work as I expected. 但是它没有按我预期的那样工作。

And the second question is, is this #define method better than using a factory of some sort? 第二个问题是,这种#define方法是否比使用某种工厂更好? I was initially doing this: 我最初是这样做的:

//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
    }
}

Are there any pros and cons to these methods, and what is the preferred one? 这些方法有什么优点和缺点,首选的方法是什么?

You seem to have a typedef with the same name as a base class (CBaseApi). 您似乎具有与基类(CBaseApi)相同名称的typedef。 That won't fare well. 那样不好。

Did you mean something like: 您的意思是:

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

The second one is terrible. 第二个太可怕了。 Two-phase initialization is very error prone, and in the general case, there is absolutely no need whatsoever for your game to change rendering APIs at run-time. 两阶段初始化非常容易出错,在一般情况下,绝对不需要您的游戏在运行时更改渲染API。 It's a complete waste of time and performance to use interfaces and inheritance, not to mention a loss of nice strong typing. 使用接口和继承完全浪费时间和性能,更不用说丢掉漂亮的强类型了。

For the #define, there is no need for the classes to be linked by inheritance. 对于#define,不需要通过继承链接类。 You might do better with a template, but conditional compilation is what the preprocessor was made for. 使用模板可能会做得更好,但是条件编译是针对预处理程序进行的。 Simple usage scenario: 简单的使用场景:

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(); }
};

Also, CClass? 还有,CClass? Owch. 哎呀 You need to find new learning materials, buddy. 您需要找到新的学习材料,伙计。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM