如何解决C++多继承类似问题

如何解决C++多继承类似问题,c++,class,namespaces,multiple-inheritance,C++,Class,Namespaces,Multiple Inheritance,我想知道什么是避免以下问题的推荐方法 我有一个类rigidBody3D,它有一个指向另一个刚体结构的指针,还有一个类box3D,它继承了rigidBody3D class rigidBody3D { public: void setPosition(float x, float y, float z); rigidBody* rb; }; class box3D : public rigidBody3D { public: box3D(float w float h,

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

我有一个类rigidBody3D,它有一个指向另一个刚体结构的指针,还有一个类box3D,它继承了rigidBody3D

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..
};
void rigidBody2D::setPosition(float x, float y)
{
    body.setPosition(x,y,0);
}
然后我有了使用这些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

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..
};
void rigidBody2D::setPosition(float x, float y)
{
    body.setPosition(x,y,0);
}
问题是:

按原样,创建box2D对象将创建两个刚体指针。一个原因是box2D继承了rigidBody2D,后者具有rigidBody3D。另一个原因是box2D有一个继承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..
};
void rigidBody2D::setPosition(float x, float y)
{
    body.setPosition(x,y,0);
}
我只想要一个刚体指针。我还希望能够调用2D类(如box2D)的2D设置位置,但也可以调用它们的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);
};
您的评论:

我想要。。。二维对象,即在二维中绘制并具有z轴的三维对象 组件设置为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
}
所有这些对象都继承自rigidBody3D,并具有指向刚体的指针

另一个问题是,事实上,一个刚体3d本身是否不应该继承自刚体,或者是否有强有力的理由反对ex:如果两者的寿命不同

备选案文2:多重继承

这里是关于box2D的设计。它是否更像一个box3D,具有相同类型的成员功能,但比一个box3D,但考虑到三维度为0?或者它更像是一个刚体,因为它应该拥有并使用这个对象提供的所有成员函数

如果你能很容易地做出决定,回到备选方案1

如果你不能决定,因为两者都有一点,那么你可以考虑多重继承:

class box2D : public box3D, public rigidBody2D {   
public:
    box2D(float w, float h);
    // no box anymore:  it's inherited from box3D 
};
然后您将继承这两者的成员函数和数据。但是多重继承并不容易。这里有两个刚体指针:从长方体继承的指针和从身体继承的指针

在您的案例中,可以通过将rigidBody3D的继承设置为虚拟来解决此问题:

class rigidBody2D : public virtual rigidBody3D { ... };
class box3D : public virtual rigidBody3D { ... };

在这种情况下,如果一个对象继承了多个时间刚体,则只创建其中一个子对象

通过让2d实体保持3d实体,您希望实现什么?您试图对什么样的真实情况建模?为什么不从三维实体继承二维实体,并将z坐标设置为0?您可能还应该更多地考虑您的设计,以及基类中应该包含的内容。我有一个指针指向的原始刚体的接口都是3D的。我想让我的3D图层尽可能靠近指针。我的2D类是为了简化我以后添加2D对象的任务,2D对象是在2D中绘制的3D对象,其z组件设置为0。我想做的是重新设计。知道我想要一个3D后端和一个简化的2D界面,你有什么建议吗?这是一个可能的解决方案。另一个是在维度数上模板化层次结构,这样您就有了对象、对象等。非常感谢!我实际上是两者的结合。