C++ 创建一种接口c++;

C++ 创建一种接口c++;,c++,frameworks,interface,C++,Frameworks,Interface,我正在编写一个带有输入和资源管理器的2d渲染框架,如纹理和网格(用于2d几何模型,如四边形),它们都包含在一个类“引擎”中,该类与纹理和网格以及directX类交互。所以每个类都有一些公共方法,比如init或update。引擎类调用它们来呈现资源、创建资源,但用户不应调用其中许多资源: //in pseudo c++ //the textures manager class class TManager { private: vector textures; ....

我正在编写一个带有输入和资源管理器的2d渲染框架,如纹理和网格(用于2d几何模型,如四边形),它们都包含在一个类“引擎”中,该类与纹理和网格以及directX类交互。所以每个类都有一些公共方法,比如init或update。引擎类调用它们来呈现资源、创建资源,但用户不应调用其中许多资源:

//in pseudo c++
//the textures manager class
class TManager
{
  private:
     vector textures;
     ....
  public:
     init();
     update();
     renderTexture();
     //called by the "engine class"

     loadtexture();
     gettexture();
     //called by the user
}


class Engine
{
private:
   Tmanager texManager;

public:
     Init() 
     { 
       //initialize all the managers
     }
     Render(){...}
     Update(){...}

     Tmanager* GetTManager(){return &texManager;} //to get a pointer to the manager 
                                                  //if i want to create or get textures
}
通过这种方式,调用Engine::GetTmanager的用户将可以访问Tmanager的所有公共方法,包括init update和rendertexture,这些方法只能由引擎在其init、render和update函数中调用。 那么,用以下方式实现用户界面是一个好主意吗

//in pseudo c++
//the textures manager class
class TManager
{
  private:
     vector textures;
     ....
  public:
     init();
     update();
     renderTexture();
     //called by the "engine class"

     friend class Tmanager_UserInterface;
     operator Tmanager_UserInterface*(){return reinterpret_cast<Tmanager_UserInterface*>(this)}
}

class Tmanager_UserInterface : private Tmanager
{
  //delete constructor
  //in this class there will be only methods like:

   loadtexture();
   gettexture();
}

class Engine
{
private:
   Tmanager texManager;

public:
     Init() 
     Render()
     Update()

     Tmanager_UserInterface* GetTManager(){return texManager;}
}

//in main function
   //i need to load a texture
   //i always have access to Engine class 

engine->GetTmanger()->LoadTexture(...) //i can just access load and get texture;
通过这种方式,我无法访问manager类,但这是一种糟糕的方式,因为如果我添加 管理器的一个新特性我需要在engine类中添加一个新方法,这需要很多时间


很抱歉英语不好。

您可以使用您的方法,但最好从public派生私有接口:

class TexManagerPublic
{
public:
    virtual void load() = 0;
    virtual void save() = 0;
};
class TexManagerPrivate : public TexManagerPublic
{
public:
    void load();
    void save();
    void init();
    void update();
};
class Engine
{
    TexManagerPrivate theTexManager;
public:
    Engine() { theTexManager.init(); }
    TexManagerPublic* texManager() { return &theTexManager; }
};
或者,您可以制作一个“引擎”作为TextureManager的朋友,如下所示:

class TexManager
{
private:
    void init();
    void update();
    friend class Engine;
};
class Engine
{
    TexManager texManager;
    void init()
    {
        texManager.init();
    }
};

每当我看到“接口”,并且故意缺少
virtual
或引用/指针时,我都会受到阻碍。而且,重新解释演员阵容应该是一个巨大的危险信号,有些事情可能不“正确”。重新解释演员阵容显然不是一个好办法。使用<代码> init <代码>函数而不是使用C++构造函数可能不是一个好的方法。有点不清楚你想要实现什么,目标是什么。我真的没有目标。但是,由于添加一个没有成员但只有方法的类不会改变类的大小,所以所有接口方法都可以工作。我简单地问自己,C++中是否可以做这样的事情,如果二进制代码总是有效的。我尝试了两个简单的类,没有错误。我已经考虑过“friend方法”,但我的只是一个例子,我的框架更复杂,类以不同的方式封装,因此有更多的“引擎私有函数”还有更多的对象,所以每个类都会有很多朋友类,这将是一片混乱。从public派生private可能是一个好主意,但由于它将是一个游戏引擎,我更喜欢避免使用虚拟函数(如果必须选择,我将保留public的“like init”函数)。我的第一个问题是,你是否可以安全地使用我的方法而不出现bug或错误。我真的看不出有什么理由避免使用虚拟函数,但如果你愿意,你可以这样做。这看起来有点奇怪,因为它会让人沮丧(设计不好的迹象)。它们的速度稍微慢一点。谢谢大家。我知道向下转换几乎是一件坏事,但它不是对向量元素的动态转换,以发现哪个派生类型是当前对象,而是一种编译时转换(以及一种更快的方法),以“建议”正确的方法来做某件事,例如IDE工具,但受语言的影响,所以我认为它没有那么糟糕,是的,有点奇怪。。。
class TexManager
{
private:
    void init();
    void update();
    friend class Engine;
};
class Engine
{
    TexManager texManager;
    void init()
    {
        texManager.init();
    }
};