基于组件的体系结构c ++

时间:2014-11-10 19:57:44

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

我无法找到在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();
}

2 个答案:

答案 0 :(得分:2)

您希望通过引用传递对象,使用

void AddComponent(Component& component);

避免任何slicing


为了正确使用std::vector<>和多态继承,您需要智能指针,例如: std::unique_ptr<Component>保留所有权,或std::shared_ptr<Component>保留共享所有权(原始指针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<>指针,您可以考虑使用std::weak_ptr<>

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

答案 1 :(得分: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