3

我有以下课程:

Collider (abstract based class)
BoxCollider
MeshCollider
SphereCollider

最后 3 个继承自 Collider。

用例是每个对撞机应该可以检查它是否与任何其他对撞机发生碰撞。

我想调用应该在 Collider 类中,看起来像:

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

现在问题来了,我应该如何定义 isCollidingWith

我想我需要为每对对撞机定义它,这意味着每种对撞机类型都应该为每种类型的对撞机提供此方法的一个版本作为参数,例如在 SphereCollider 中:

class SphereCollider : public Collider
{

bool isCollidingWith(SphereCollider* c){..}
bool isCollidingWith(BoxCollider* c){..}
bool isCollidingWith(MeshCollider* c){..}

};

为了确保这些方法可以通过 Collider 基类访问,我需要定义

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

此外,由于调用this->isCollidingWith(*it)只需要一个指向 Collider 而不是派生类的指针,我希望列出的那些虚拟方法的适当方法在运行时自动采用。然而,情况似乎并非如此:因为参数只是 Collider,它会寻找一个只有 Collider* 参数的方法。

我能想到的唯一解决方案是在 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 ...
}

这不是很优雅。有没有其他(适当的)方法来处理这种情况?谢谢!

4

2 回答 2

4

这是双重调度的情况。不会在这里详细说明它,因为它是一个已经被广泛使用的成语,即使维基百科页面已经过时,使用该术语进行简单的谷歌搜索也会产生良好的结果。

于 2012-11-05T19:08:19.190 回答
-1

因为您从 Collider 继承了 BoxCollider、MeshCollider 和 SphereCollider,所以您不需要创建 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){..}
};

因为方法 isCollidingWith 是虚拟的,在运行时,由于多态性,将根据调用它的对象调用正确的方法(并且如果继承的类具有 isCollidingWith(Collider *c) 的实现,否则继承的类将也变得抽象)。

例子:

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

希望这可以帮助。

于 2012-11-05T19:08:06.210 回答