我目前有一个类'WorldObject',它包含一个指向其b2Body的指针,以及几个方法和变量。但是,使WorldObject成为b2Body的派生类不是更聪明吗?对于这类事情,一般的方法是什么?,总是创建一个类中最重要的对象的派生类,还是只创建一个新的,并使所有的对象都具有属性?这些可能性的利弊是什么?谢谢你。
fcg9iug31#
没有最好的办法,这完全取决于具体情况:
b2Body
WorldObject
b2Boby
经验法则是选择preferring composition over inheritance,除非你真的有明显的继承。在您的示例中,b2Body是刚体。现在问您一个问题:你的对象是一个身体吗?或者你的对象是身体吗?更实用:这种设计的优势在于它将Box2D引擎的选择封装在WorldObject中。如果以后您使用另一个API将软件移植到另一个物理引擎,这将使您能够更好地控制影响。如果您使用继承,底层引擎API将显著影响您自己软件的设计,并使其在某一天很难移植到另一个引擎。
gzjq41n42#
通常最好进行组合,而不要过度使用继承。还要注意,通常创建一个调用b2World::CreateBody()的主体,它返回一个b2Body*,并具有不可能的继承。为了避免内部b2Body*的生存期问题,你可以使用智能指针。
b2World::CreateBody()
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的实际子类中:
class SpaceShip : public WorldObject { public: SpaceShip(b2World *world) :WorldObject(world) { //initialize bodydef and whatever m_body.reset(world->CreateBody(...)); } };
l2osamch3#
你一定更喜欢复合而不是继承。复合避免了fragile base class problem。
我建议您阅读约书亚Bloch的《有效的Java》一书中的第16条“更喜欢组合而不是继承
3条答案
按热度按时间fcg9iug31#
没有最好的办法,这完全取决于具体情况:
b2Body
的指针实现了组合关系,即WorldObject
具有b2Body
。WorldObject
从b2Body
派生实现了继承,并且只有当WorldObject
是b2Body
时才应该这样做。这意味着原则上,你可以用WorldObject
对象做你可以用b2Boby
做的任何事情(甚至更多)。经验法则是选择preferring composition over inheritance,除非你真的有明显的继承。
在您的示例中,
b2Body
是刚体。现在问您一个问题:你的对象是一个身体吗?或者你的对象是身体吗?更实用:这种设计的优势在于它将Box2D引擎的选择封装在
WorldObject
中。如果以后您使用另一个API将软件移植到另一个物理引擎,这将使您能够更好地控制影响。如果您使用继承,底层引擎API将显著影响您自己软件的设计,并使其在某一天很难移植到另一个引擎。gzjq41n42#
通常最好进行组合,而不要过度使用继承。
还要注意,通常创建一个调用
b2World::CreateBody()
的主体,它返回一个b2Body*
,并具有不可能的继承。为了避免内部
b2Body*
的生存期问题,你可以使用智能指针。然后,在
WorldObject
中:然后,在
WorldObject
的实际子类中:l2osamch3#
你一定更喜欢复合而不是继承。复合避免了fragile base class problem。
我建议您阅读约书亚Bloch的《有效的Java》一书中的第16条“更喜欢组合而不是继承