我想知道以下是避免此问题的推荐方法。
我有一个类rigidBody3D,它有一个指向另一个rigidBody结构的指针,以及一个继承rigidBody3D的类box3D。
class rigidBody3D {
public:
void setPosition(float x, float y, float z);
rigidBody* rb;
};
class box3D : public rigidBody3D {
public:
box3D(float w float h, float l);
..other box functions..
};
然后我有使用这些3D类的2D类。
class rigidBody2D {
public:
rigidBody2D();
void setPosition(float x, float y);
rigidBody3D body;
};
class box2D : public rigidBody2D {
public:
box2D(float w, float h);
box3D box;
};
例如,rigidBody2D的setPosition调用其rigidBody3D的3D setPosition。
void rigidBody2D::setPosition(float x, float y)
{
body.setPosition(x,y,0);
}
问题:
按原样,创建box2D对象会创建两个rigidBody指针。一个是因为box2D继承了rigidBody2D,它具有rigidBody3D。另一个是因为box2D有一个box3D对象,它继承了rigidBody3D。
我只想要一个rigidBody指针。我也希望能够像box2D那样为2D类调用2D setPosition,还可以调用他们的3D特定函数,比如box2D调用box3D。
解决方案:
我使用虚拟继承来解决问题,并且继承了3D类而不是拥有它们的对象。
class rigidBody3D {
public:
void setPosition(float x, float y, float z);
rigidBody* rb;
};
class box3D : public virtual rigidBody3D {
public:
box3D(float w float h, float l);
..other box functions..
};
class rigidBody2D : private virtual rigidBody3D {
public:
rigidBody2D();
void setPosition(float x, float y);
};
class box2D : public rigidBody2D, private box3D {
public:
box2D(float w, float h);
};
void rigidBody2D::setPosition(float x, float y)
{
rigidBody3D::setPosition(x,y,0);
}
答案 0 :(得分:0)
setPosition
的语义对于这两个概念是不同的。
另一种说法是2d主体不是种 3d主体,它是一个不同的概念,所以看起来它们之间应该没有继承关系。
所以我会从这些思路开始思考:
struct rigid_body_3d_concept {
virtual ~rigid_body_3d_concept();
void set_position(double x, double y, double z) {
_impl->really_set_the_position(x, y, z);
}
private:
rigidbody* _impl;
};
struct rigid_body_2d_concept {
virtual ~rigid_body_2d_concept();
void set_position(double x, double y) {
_impl->really_set_the_position(x, y, 0);
}
private:
rigidbody* _impl;
};
struct box3d
: public rigid_body_3d_concept
{
box3d(double w, double h, double l);
};
struct box2d
: public rigid_body_2d_concept
{
box2d(double w, double h);
};
答案 1 :(得分:0)
您的评论:
我想要(...)2D对象,这些对象是以2D绘制并具有z的3D对象 组件设置为0
强烈建议rigidBody2D
是 rigidBody3D
,而box2D
是 box3D
。因此,更喜欢继承而不是复合似乎很自然:
备选方案1:简单继承
这里我们将考虑所有这些2D和3D对象的根是rigidBody2D。 还有一个问题是:box2D是一种box3D还是更多的rididBody2D?
class rigidBody2D : public rigidBody3D {
public:
rigidBody2D();
void setPosition(float x, float y);
// no body anymore: it's inherited from rigidBody3D
};
class box2D : public box3D { // is it more like a box3d or more like a rigiBbody2D ? You decide !
public:
box2D(float w, float h);
// no box anymore: it's inherited from box3D
};
box2D::box2D (float w, float h) : box3D (w, h, 0) { /*...*/ } // how to create a box2D as a special case of box3D
void rigidBody2D::setPosition(float x, float y) // call the setpos of the parent.
{
rigidBody3D::setPosition(x, y, 0); // call parent's setpos
}
所有therse对象都继承自rigidBody3D
,然后指向rigidBody
。
另一个问题实际上是要知道rigidBody3D
本身是否应该从rigidBody
继承,或者是否存在强烈的反对意见(例如:如果两者的生命周期不同) 。
备选方案2:多重继承
这是关于box2D的设计。它是一个box3D,具有相同类型的成员函数,但比box3D,但考虑到第三个维度是0?或者它更像是rigidBody2D,因为它应该拥有并使用这个对象提供的所有成员函数?
如果您可以轻松决定,请返回备选方案1.
如果您无法决定,因为它们两者兼而有之,那么您可以考虑多重继承:
class box2D : public box3D, public rigidBody2D {
public:
box2D(float w, float h);
// no box anymore: it's inherited from box3D
};
你会继承成员(两者的功能和数据)。 Hower多重继承并不容易。你在这里有2个刚体指针:从盒子中继承的那些,以及从体内继承的那些。
这个问题可以通过继承rigidBody3D virtual来解决你的问题:
class rigidBody2D : public virtual rigidBody3D { ... };
class box3D : public virtual rigidBody3D { ... };
在这种情况下,如果一个对象继承了几个时间rigidBody3D,则只创建一个这样的子对象。