如何解决这个C ++多重继承类似的问题

时间:2014-11-27 18:10:06

标签: c++ class namespaces multiple-inheritance

我想知道以下是避免此问题的推荐方法。

我有一个类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);
}

2 个答案:

答案 0 :(得分: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);
};

答案 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,则只创建一个这样的子对象。