我目前有一个类“WorldObject”,其中包含一个指向其b2Body的指针,以及几个方法和变量。派生类的b2Body或包含b2Body对象的类?
但是,将WorldObject作为b2Body的派生类会更聪明吗?
这种事情的一般方法是什么?要始终创建类中最重要的对象的派生类,或者创建一个新类并创建所有属性?
这些可能性的优缺点是什么?
谢谢。
我目前有一个类“WorldObject”,其中包含一个指向其b2Body的指针,以及几个方法和变量。派生类的b2Body或包含b2Body对象的类?
但是,将WorldObject作为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(...));
}
};
没有最好的办法。这一切取决于上下文:
有一个指针b2Body
实现组合物的关系,即WorldObject
具有b2Body
。
制作WorldObject
从b2Body
implemetns继承获得的,如果一个WorldObject
是b2Body
应只完成。这意味着原则上你可以用一个WorldObject
对象来做一切你可以用b2Boby
(以及更多)做的事情。
经验法则是去preferring composition over inheritance。除非你真的有明显的继承。
就你而言,b2Body
是一个刚体。现在给你一个问题:你的对象是一个身体吗?或者你的对象是一个身体?
更实用:此设计的优点是它将Box2D引擎的选择封装在您的WorldObject
中。如果稍后将软件移植到另一个使用其他API的物理引擎,则可以更好地控制影响。如果你使用继承,底层的引擎API会对你自己的软件的设计产生重大影响,并且有一天很难迁移到另一个引擎。
你一定喜欢,组成了继承。构图避免了fragile base class problem。
不像方法调用,继承违反了封装
子类取决于它们的父类,其可以被改变,如在子类
结果破碎功能使用组合物和转发,而不是继承,特别是如果存在一个适当的接口来实现一个包装类。
使用继承时,类是专为继承
我建议你由约书亚布洛赫
“在继承青睐组成”中的“有效的Java”一书的阅读项目16