2016-04-03 85 views
1

我目前有一个类“WorldObject”,其中包含一个指向其b2Body的指针,以及几个方法和变量。派生类的b2Body或包含b2Body对象的类?

但是,将WorldObject作为b2Body的派生类会更聪明吗?

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

这些可能性的优缺点是什么?

谢谢。

回答

2

通常情况下最好是做组合,不要过度使用继承。

还请注意,您通常会创建一个调用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(...)); 
    } 
}; 
3

没有最好的办法。这一切取决于上下文:

  • 有一个指针b2Body实现组合物的关系,即WorldObject具有b2Body

  • 制作WorldObjectb2Body implemetns继承获得的,如果一个WorldObjectb2Body应只完成。这意味着原则上你可以用一个WorldObject对象来做一切你可以用b2Boby(以及更多)做的事情。

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

就你而言,b2Body是一个刚体。现在给你一个问题:你的对象是一个身体吗?或者你的对象是一个身体?

更实用:此设计的优点是它将Box2D引擎的选择封装在您的WorldObject中。如果稍后将软件移植到另一个使用其他API的物理引擎,则可以更好地控制影响。如果你使用继承,底层的引擎API会对你自己的软件的设计产生重大影响,并且有一天很难迁移到另一个引擎。

0

你一定喜欢,组成了继承。构图避免了fragile base class problem

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

  • 子类取决于它们的父类,其可以被改变,如在子类

    结果破碎功能
  • 使用组合物和转发,而不是继承,特别是如果存在一个适当的接口来实现一个包装类。

  • 使用继承时,类是专为继承

我建议你由约书亚布洛赫

“在继承青睐组成”中的“有效的Java”一书的阅读项目16