派生类b2Body还是包含b2Body对象的类?

时间:2016-04-03 21:53:14

标签: c++ box2d

我目前有一个'WorldObject'类,它包含一个指向b2Body的指针,以及几个方法和变量。

但是让WorldObject成为b2Body的派生类并不聪明吗?

这类事情的一般方法是什么?要始终在类中创建最重要对象的派生类,还是只创建一个新类并创建所有属性?

这些可能性有哪些优点和缺点?

谢谢。

3 个答案:

答案 0 :(得分:3)

没有最好的办法。这完全取决于具体情况:

  • 指向b2Body的指针实现了合成关系,即WorldObject具有b2Body

  • 使WorldObject派生自b2Body实现继承,并且仅在WorldObjectb2Body时才会执行。这意味着原则上您可以使用WorldObject对象执行使用b2Boby(以及更多)执行的所有操作。

经验法则是preferring composition over inheritance。除非你真的有明显的继承。

在你的情况下,b2Body是一个僵硬的身体。现在问你一个问题:你的对象是一个身体吗?或者你的对象是一个身体?

更实用:这种设计的优势在于它将Box2D引擎的选择封装在WorldObject中。这使您可以在以后使用其他API将软件移植到另一个物理引擎时更好地控制影响。如果您使用继承,则底层引擎API将显着影响您自己软件的设计,并使其有一天很难迁移到另一个引擎。

答案 1 :(得分:2)

做作文通常更好,不要过度使用继承。

另请注意,您通常会创建一个调用module.exports = { main: { files: [{ expand: true, cwd: "build/css/", src: "style.css", dest: "../" }] }, } 的正文,并返回b2World::CreateBody(),并且继承是不可能的。

为了避免内部b2Body*的生命周期问题,您可以使用智能指针。我使用这个定义:

b2Body*

然后,在我的class BodyDeleter { public: BodyDeleter() :m_world(NULL) {} BodyDeleter(b2World *world) :m_world(world) {} void operator()(b2Body *body) { if (m_world) m_world->DestroyBody(body); } private: b2World *m_world; }; typedef std::unique_ptr<b2Body, BodyDeleter> b2BodyPtr;

WorldObject

然后,在class WorldObject { protected: WorldObject(b2World *world) :m_body(NULL, m_world) {} b2BodyPtr m_body; }; 的实际子类中:

WorldObject

答案 2 :(得分:0)

你必须更喜欢,合成而不是继承。该构图避免使用fragile base class problem

  • 与方法调用不同,继承违反了封装

  • 子类依赖于它们的超类,它们可能会被更改,因此子类中的功能会被破坏

  • 使用组合和转发而不是继承,尤其是在存在实现包装类的适当接口时。

  • 当class设计用于继承时使用继承

我建议你阅读Joshua bloch撰写的“有效Java”一书中的第16项“赞成合成而非继承”