C++;关于继承和铸造的问题 我目前正在为一个学校项目做业余物理引擎,但我因为C++问题而陷入困境。设置如下所示:

C++;关于继承和铸造的问题 我目前正在为一个学校项目做业余物理引擎,但我因为C++问题而陷入困境。设置如下所示:,c++,inheritance,casting,overloading,C++,Inheritance,Casting,Overloading,我有三门不同的课: 刚体(摘要) 球体(从刚体继承) 自定义刚体(从刚体继承并表示多面体) 我需要检查两个同名方法的两个实体之间是否发生碰撞。一个用于检查与球体的接触,而另一个用于检查与自定义刚体的接触。有几种可能的场景(球体/球体碰撞、球体/自定义碰撞等),因此这两种方法都是在所有这些类中定义的 在刚体中,它们是抽象的: virtual bool isCollidingWith(Sphere* s_p) = 0; virtual bool isCollidingWith(CustomRig

我有三门不同的课:

  • 刚体(摘要)
  • 球体(从刚体继承)
  • 自定义刚体(从刚体继承并表示多面体)
我需要检查两个同名方法的两个实体之间是否发生碰撞。一个用于检查与球体的接触,而另一个用于检查与自定义刚体的接触。有几种可能的场景(球体/球体碰撞、球体/自定义碰撞等),因此这两种方法都是在所有这些类中定义的

在刚体中,它们是抽象的:

virtual bool isCollidingWith(Sphere* s_p) = 0;
virtual bool isCollidingWith(CustomRigidBody* rb_p) = 0;
但不是在这个领域:

bool isCollidingWith(Sphere* s_p);
bool isCollidingWith(CustomRigidBody* rb_p);
也不是在自定义刚体中:

bool isCollidingWith(Sphere* s_p);
bool isCollidingWith(CustomRigidBody* rb_p);
在我的主程序中,我有一个
std::vector
,其中包含指向刚体(超类)的指针,我需要通过调用以下命令成对检查对象之间的冲突:

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;
我的猜测是,这与物体向量包含指向刚体的指针这一事实有关,它们不会自动转换为球体*或自定义刚体*,但我不知道如何解决这个问题

感谢您的帮助;)

这个问题通过以下方法解决。本质上,您需要向
刚体及其派生类添加另一个重载:

bool isCollidingWith(RigidBody* rb_p) = 0;
在派生类中,例如
Sphere
,实现如下所示:

bool Sphere::isCollidingWith(RigidBody* rb_p)
{
    return rb_p->isCollidingWith(this);
}
这是因为第一次调用
isCollidingWith
时(在循环中),会调用正确派生类的
isCollidingWith(RigidBody*)
版本(通过虚方法)。然后,在
Sphere::isCollidingWith(RigidBody*)
中,通过虚方法使用正确的派生类。但是,这次,
this
是一个
Sphere*
,因此调用的重载是
isCollidingWith(Sphere*)
版本

换言之:

  • 在您的循环中:

    this->bodies_p[i]->isCollidingWith(this->bodies_p[j])
    
    将调用
    Sphere::isCollidingWith(刚体*)
    CustomRigidBody::isCollidingWith(刚体*)
    ,具体取决于
    实体的实际类型。假设它是一个
    球体
    ,那么我们得到

  • Sphere::isCollidingWith(刚体*rb\u p)

    它调用
    Sphere::isCollidingWith(Sphere*)
    CustomRigidBody::isCollidingWith(Sphere*)
    ,具体取决于
    rb\u p
    的实际类型

  • 这个问题是用计算机解决的。本质上,您需要向
    刚体及其派生类添加另一个重载:

    bool isCollidingWith(RigidBody* rb_p) = 0;
    
    在派生类中,例如
    Sphere
    ,实现如下所示:

    bool Sphere::isCollidingWith(RigidBody* rb_p)
    {
        return rb_p->isCollidingWith(this);
    }
    
    这是因为第一次调用
    isCollidingWith
    时(在循环中),会调用正确派生类的
    isCollidingWith(RigidBody*)
    版本(通过虚方法)。然后,在
    Sphere::isCollidingWith(RigidBody*)
    中,通过虚方法使用正确的派生类。但是,这次,
    this
    是一个
    Sphere*
    ,因此调用的重载是
    isCollidingWith(Sphere*)
    版本

    换言之:

  • 在您的循环中:

    this->bodies_p[i]->isCollidingWith(this->bodies_p[j])
    
    将调用
    Sphere::isCollidingWith(刚体*)
    CustomRigidBody::isCollidingWith(刚体*)
    ,具体取决于
    实体的实际类型。假设它是一个
    球体
    ,那么我们得到

  • Sphere::isCollidingWith(刚体*rb\u p)

    它调用
    Sphere::isCollidingWith(Sphere*)
    CustomRigidBody::isCollidingWith(Sphere*)
    ,具体取决于
    rb\u p
    的实际类型


  • 漂亮的“把戏”。甚至停止添加我的答案,因为这比我的解决方案好得多。谢谢你的答案和详细解释!您粘贴的Wikipedia链接甚至引用物理模拟作为使用双重分派的特征情况之一=D@RedX:这里也一样。天哪,我爱你德妮丝“把戏”。甚至停止添加我的答案,因为这比我的解决方案好得多。谢谢你的答案和详细解释!您粘贴的Wikipedia链接甚至引用物理模拟作为使用双重分派的特征情况之一=D@RedX:这里也一样。天哪,我爱你D