虚拟方法和参数查找

Virtual methods and parameters lookup

本文关键字:查找 参数 方法 虚拟      更新时间:2023-10-16

我有以下类:

Collider (abstract based class)
BoxCollider
MeshCollider
SphereCollider

最后3个从对撞机上继承。

用例是,每个对撞机都应该检查它是否与其他任何围墙碰撞。

我想电话应该在对撞机课上,看起来像:

void Collider::checkCollisionsWithOtherColliders()
{
for(std::vector<Collider*>::iterator it ....)
{
if(this->isCollidingWith(*it){...}
}
}

现在出现的问题我应该如何定义iscolliding

我想我需要为每对山脉定义它,这意味着每种撞机类型都应为每种类型的对撞机作为参数,例如在spherecollider中:

class SphereCollider : public Collider
{
bool isCollidingWith(SphereCollider* c){..}
bool isCollidingWith(BoxCollider* c){..}
bool isCollidingWith(MeshCollider* c){..}
};

要确保通过对撞机基类访问此类方法,我需要定义

class Collider
{
virtual bool isCollidingWith(SphereCollider* c){..}
virtual bool isCollidingWith(BoxCollider* c){..}
.. and so on
};

另外,由于呼叫this->isCollidingWith(*it)仅采用一个指针,而不是派对类,因此我希望在运行时自动采用这些虚拟方法的适当方法。但是,似乎并非如此:由于参数只是对撞机,因此它寻找一种使用Collider*参数的方法。

我唯一能想到的解决方案是在对撞机中定义:

bool isCollidingWith(Collider* collider)
{
if (0 != dynamic_cast<SphereCollider*>(collider))
return isCollidingWith(dynamic_cast<SphereCollider*>(collider));
else if (0 != dynamic_cast<BoxCollider*>(collider))
return isCollidingWith(dynamic_cast<BoxCollider*>(collider));
else if ...
}

不是真正优雅的。还有其他(适当的)处理此类情况的方法吗?谢谢!

这是 double Dispatch 的情况。在这里不会详细介绍它,因为它是一个已经广泛使用的成语,即使Wikipedia页面已过时,该术语的简单Google搜索也将产生不错的结果。

,因为您正在从撞机子里继承boxcollider,网格集团和sphecollider,所以您无需创建3种不同的方法来接受每个类的参数。这就是为什么OOP很棒。

您可以使用以下方式:

class Collider
{
    virtual bool isCollidingWith(Collider* c){..}
};
class SphereCollider : public Collider
{
    bool isCollidingWith(Collider* c){..}
};
class BoxCollider : public Collider
{
    bool isCollidingWith(Collider* c){..}
};
class MeshCollider : public Collider
{
    bool isCollidingWith(Collider* c){..}
};

由于通过多态性而在运行时进行iScolliding与虚拟时间是虚拟的,因此将基于调用它的对象调用正确的方法(前提继承的类也将变得抽象)。

示例:

Collider *c1 = new SphereCollider;
Collider *c2 = new BoxCollider;
Collider *c3 = new MeshCollider;
// To check if Sphere is colliding with anything
// This will go to the implementation in SphereCollider
c1->isCollidingWith(c2);
c1->isCollidingWith(c3);
// To check if Box is colliding with anything
// This will go to the implementation in BoxCollider
c2->isCollidingWith(c1);
c2->isCollidingWith(c3);
// To check if Mesh is colliding with anything
// This will go to the implementation in MeshCollider
c3->isCollidingWith(c1);
c3->isCollidingWith(c2);

希望这会有所帮助。