【问题标题】:Component based architecture c++基于组件的架构 C++
【发布时间】:2015-01-07 05:43:14
【问题描述】:

我在想办法用 C++ 制作基于组件的引擎架构时遇到了麻烦。但是我想不出一种方法来将组件向量与从组件派生的类结合起来。

我想覆盖组件的虚拟功能。但是我可以让它调用覆盖函数的唯一方法是使组件派生类成为一个指针,但我希望每个游戏对象都在一个向量中包含自己的组件,而不是在类之外作为指针。

我试图尽可能多地删除不必要的代码。

我的结构:

//GameObject class, contains components and other objects
class GameObject
{
public:

    GameObject(){}
    ~GameObject(){}

    void AddChild(GameObject child)
    {
       children.push_back(child);
    }
    void AddComponent(Component component)
    {
       components.push_back(component);
    }

    void Input(){}
    void Update(){}
    void Render()
    {
       for(unsigned int i = 0; i < components.size(); i++)
            components[i].Render();
    }

private:

    std::vector<GameObject> children;
    std::vector<Component> components;
};

//base class component
class Component
{
public:
    Component(){}
    ~Component(){}

    virtual void Input(){}
    virtual void Update(){}
    virtual void Render(){ cout << "Component -> Render()" << endl; }

};

class MeshRenderer : public Component
{
public:
    MeshRenderer(Mesh _mesh, Material _material)
    {
        mesh = _mesh;
        material = _material
    }

    ~MeshRenderer(){}

    //override components virtual Render()
    void Render(Transform transform)
    {
        mesh.Render(material);
        cout << "MeshRenderer -> Render()" << endl;
    }

private:
    Mesh mesh;
    Material material;
};

GameObject* root = new GameObject();
MeshRenderer meshRenderer(mesh, material);

root->AddComponent(meshRenderer);

//GameLoop
while(!quit)
{
   root->Render();
}

【问题讨论】:

  • 也许使用指针向量?或者甚至是智能指针的向量?
  • 只是想知道。您打算如何使用此设计检索组件?
  • @Veritas 好点。

标签: c++ architecture components derived-class derived


【解决方案1】:

看起来你想通过引用传递你的对象,使用

void AddComponent(Component& component);

避免任何slicing


为了正确使用std::vector&lt;&gt; 和多态继承,您需要智能指针,例如std::unique_ptr&lt;Component&gt; 保留所有权,或 std::shared_ptr&lt;Component&gt; 共享所有权(原始指针 Component* 也可以工作,但更难正确管理)。

void AddComponent(std::unique_ptr<Component> componentPtr); // Unique ownership

void AddComponent(std::shared_ptr<Component> componentPtr); // Shared ownership

因此

std::vector<std::unique_ptr<Component>> components;

std::vector<std::shared_ptr<Component>> components;

这些 Component 实例是否应该由它们的聚合父 GameObject 类唯一拥有,这取决于您的实际用例。


要使用 std::shared&lt;&gt; 指针,可能会在其使用范围之外过期,您可以考虑使用 std::weak_ptr&lt;&gt;

如前所述,这完全取决于您的用例,以及您希望如何从 GameObject 类外部访问这些聚合组件。

【讨论】:

    【解决方案2】:

    如果你能用unique_ptr就最好了:

    void AddComponent(std::unique_ptr<Component> component) {
        components.push_back(std::move(component));
    }
    
    std::vector<std::unique_ptr<Component>> components;
    

    因此,通过调用AddComponent(),您将组件的所有权转移到包含GameObject

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2023-03-09
      • 1970-01-01
      • 2011-05-19
      • 2011-02-23
      • 1970-01-01
      • 2017-01-11
      • 2019-07-19
      相关资源
      最近更新 更多