关于继承和转换的C ++问题

时间:2011-02-28 22:42:49

标签: c++ inheritance casting overloading

我目前正在为一个学校项目开发一个业余物理引擎,但我因为C ++问题而陷入困境。设置如下:

我有三个不同的类:

  • RigidBody(摘要)
  • Sphere(继承自RigidBody)
  • CustomRigidBody(继承自RigidBody并代表多面体)

我需要检查一对具有两个同名方法的物体之间是否发生碰撞。一个用于检查与Sphere的联系,而另一个用于检查与CustomRigidBody的联系。有几种可能的场景(球体/球体碰撞,球体/自定义碰撞等......)所以这两种方法都是在所有这些类中定义的。

在RigidBody中,它们是抽象的:

virtual bool isCollidingWith(Sphere* s_p) = 0;
virtual bool isCollidingWith(CustomRigidBody* rb_p) = 0;

但不在Sphere:

bool isCollidingWith(Sphere* s_p);
bool isCollidingWith(CustomRigidBody* rb_p);

也不在CustomRigidBody中:

bool isCollidingWith(Sphere* s_p);
bool isCollidingWith(CustomRigidBody* rb_p);

在我的主程序中,我有一个std::vector<RigidBody*>包含指向RigidBodies(超类)的指针,我需要通过调用以下内容来检查对象之间的冲突:

for(int i = 1; i < this->bodies_p.size(); ++i)
    for(int j = 0; j < i; ++j)
        if(this->bodies_p[i]->isCollidingWith(this->bodies_p[j]))
            std::cout << " COLLISION BETWEEN " << i << " AND " << j << std::endl;

我的印象是C ++可以正常使用,但我收到以下错误消息:

Engine.cc:35: error: no matching function for call to ‘RigidBody::isCollidingWith(RigidBody*&)’
RigidBody.h:53: note: candidates are: virtual bool RigidBody::isCollidingWith(Sphere*)
RigidBody.h:54: note:                 virtual bool        RigidBody::isCollidingWith(CustomRigidBody*)

我的猜测是,它与body的向量包含指向RigidBodies的指针这一事实有关,它们不会自动转换为Sphere *或CustomRigidBody *但我不知道如何解决这个问题。

感谢您的帮助;)

1 个答案:

答案 0 :(得分:4)

Double Dispatch解决了这个问题。实质上,您需要为RigidBody及其派生类添加另一个重载:

bool isCollidingWith(RigidBody* rb_p) = 0;

在派生类中,例如Sphere,实现如下:

bool Sphere::isCollidingWith(RigidBody* rb_p)
{
    return rb_p->isCollidingWith(this);
}

这是有效的,因为第一次调用isCollidingWith(在你的循环中),来自正确派生类的isCollidingWith(RigidBody*)版本被调用(通过虚方法)。然后,在Sphere::isCollidingWith(RigidBody*)中,通过虚方法使用正确的派生类。但是,这次thisSphere*,因此调用的重载是isCollidingWith(Sphere*)版本。

换句话说:

  1. 在你的循环中:

    this->bodies_p[i]->isCollidingWith(this->bodies_p[j])
    

    会调用Sphere::isCollidingWith(RigidBody*)CustomRigidBody::isCollidingWith(RigidBody*),具体取决于bodies_p[i]的实际类型。假设它是Sphere,那么我们得到

  2. Sphere::isCollidingWith(RigidBody* rb_p)

    return rb_p->isCollidingWith(this);
    

    调用Sphere::isCollidingWith(Sphere*)CustomRigidBody::isCollidingWith(Sphere*),具体取决于rb_p的实际类型。

相关问题