[英]How to solve this C++ multiple inheritance similar issue
我想知道推荐什么方法来避免出现以下问题。
我有一个拥有指向另一个刚性主体结构的指针的刚性主体3D类,以及一个继承刚性主体3D的类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调用其刚性Body3D的3D setPosition。
void rigidBody2D::setPosition(float x, float y)
{
body.setPosition(x,y,0);
}
问题:
照原样,创建一个box2D对象将创建两个刚性指针。 一个原因是box2D继承了具有rigidBody3D的rigidBody2D。 另一个原因是box2D有一个box3D对象,该对象继承了rigidBody3D。
我只想要一个僵尸指针。 我还希望能够为2D类(如box2D)调用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);
}
在我看来,2d和3d对象仅通过以刚体*的形式实现而相关。 对于这两个概念, 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);
};
你的评论:
我想要(...)2D对象,这是2D绘制的3D对象,其z分量设置为0
有力地表明, rigidBody2D
是 rigidBody3D
,和一个box2D
是 box3D
。 因此,与继承相比,继承似乎更自然:
备选方案1:简单继承
在这里,我们将考虑所有这些2D和3D对象的根是刚性对象2D。 仍然存在一个问题: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
}
所有这些对象都继承于rigidBody3D
并且具有指向rigidBody
的指针。
进一步的问题是,实际上知道是否rigidBody3D
不应该自己从继承rigidBody
,或者有强烈的反对论据(为前:如果两个的寿命是不同的)。
备选方案2:多重继承
这是关于box2D的设计的。 考虑到三维尺寸为0,它是否比box3D更具有相同类型的成员函数的box3D? 还是因为它应该具有并使用此对象提供的所有成员函数,而使它更像是一个ttyBody2D?
如果您可以轻松决定,请返回至备选方案1。
如果您不能决定,因为两者兼有,那么您可以考虑多重继承:
class box2D : public box3D, public rigidBody2D {
public:
box2D(float w, float h);
// no box anymore: it's inherited from box3D
};
然后,您将继承成员(两者的功能和数据)。 如何进行多重继承并不容易。 在这里,您将有2个刚性主体指针:那些从盒子继承的指针和那些从主体继承的指针。
在您的情况下,可以通过使rigidBody3D继承为虚拟来解决此问题:
class rigidBody2D : public virtual rigidBody3D { ... };
class box3D : public virtual rigidBody3D { ... };
在这种情况下,如果一个对象继承了几个时间的linearBody3D,则只会创建一个此类子对象。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.