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

标签 c++ inheritance casting overloading

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

我有三个不同的类:

  • 刚体(摘要)
  • 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(父类(super class))的指针,我需要通过调用类似的方法成对检查对象之间的碰撞:

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*)

我的猜测是,它与以下事实有关:主体 vector 包含指向 RigidBodies 的指针,并且它们不会自动转换为 Sphere* 或 CustomRigidBody*,但我不知道如何解决该问题。

感谢您的帮助;)

最佳答案

此问题由 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 的实际类型.

关于关于继承和转换的 C++ 问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5148458/

相关文章:

c++ - g++/minGW 可以与 Windows SDK 配合使用吗? Visual Studio 是唯一的选择吗?

c++ - 析构函数如何执行?

c# - 测量类型之间的关系继承距离

c++ - 将指针转换为指针引用会导致未定义的行为吗?

xml - 如何确定 Powershell 中的 XML 类型?

c++ - 条件变量在被通知之前唤醒

c++ - 参数类型取决于结构内部的模板化结构的友元函数

c# - 从基类继承并提供继承类型给覆盖的方法

java - 访问 protected 成员时出错

c# - 为什么 Select(x => ...Cast<x.GetType()>()) 不起作用?