gpt4 book ai didi

c++ - 构图模式

转载 作者:搜寻专家 更新时间:2023-10-31 00:39:58 25 4
gpt4 key购买 nike

应该如何处理组合而不是继承?考虑以下类:

class GameObject {...};

class Sprite {
public:
void changeImage(...);
};

class VisibleGameObject: public Sprite, public GameObject {};

class VisibleGameObject : public GameObject {
protected:
Sprite m_sprite;
};

第一个 VisibleGameObject 类使用继承。多重继承。看起来不太好。第二个是我想使用的,但它不允许我像这样访问 Sprite 的 API:

VisibleGameObject man;
man.changeImage();

如何在没有继承(或代码重复)的情况下实现这一点?

编辑:我知道我可以只使用继承或使 m_sprite 成为公共(public)成员,但我无法访问 Sprite 类,因为它是 private。这就是重点,问题是关于根据数据封装规则更改 VisibleGameObject 的 Sprite 的最佳方法。

最佳答案

我认为您仍然落后于“组合优于继承”的思维方式。基类应该知道要合成什么。要改变图像,你应该改变 Sprite 实例,你不应该提供组合实例的接口(interface)。例如:

class GameObject {
public:
// you can choose public access or getters and setters, it's your choice
Sprite sprite;
PhysicalBody body;
};

object = GameObject();
object.sprite = graphicalSystem.getSpriteFromImage("image.png");
// or if you prefer setters and getters
object.setSprite(sprite);

更一般地说,GameObject 应该包含基类 Component 的实例(或指向实例的指针,取决于您的实现)。在这种情况下使用继承是有意义的,因为这样它们就可以像 std::map 一样在一个存储中。例如:

class Component {
// ...
};

class Sprite : public Component {
//...
};

class PhysicalBody : public Component {
//...
};

class GameObject {
protected:
std::map<std::string, Component*> components;
//...
public:
Component* getComponent(const std::string& name) const;
void setComponent(const std::string& name, Component* component);
//...
};

要在主循环中创建组件和渲染,请使用 Systems。例如,GraphicalSystem 知道它创建的所有 Sprite 实例,并且在渲染时它只渲染附加到某个 GameObject 实例的 Sprite 。分离的组件可以被垃圾收集。有关位置和大小的信息可能是游戏对象的一部分,也可能是“物理”组件。

理解它的最好方法是编写您自己的原型(prototype)或检查现有的实现(ArtemisUnity 3D 和许多其他)。有关详细信息,请参阅 Cowboy programming: Evolve Your Hierarchy或尝试查找实体/组件系统。

关于c++ - 构图模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15562357/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com