gpt4 book ai didi

C++在不知道派生类的情况下将基类指针转换为派生类

转载 作者:塔克拉玛干 更新时间:2023-11-03 07:19:21 26 4
gpt4 key购买 nike

我有各种类型的碰撞器类(SphereCollider、AABBCollider 等),它们都继承自基类 Collider。我使用指向基类的指针将它们存储在 std::vector 中。

std::vector<std::shared_ptr<Collider>> colliders;

然后我有各种函数来计算碰撞器是否相互交叉。

bool Colliding(const SphereCollider& colliderOne, const SphereCollider& colliderTwo);
bool Colliding(const AABBCollider& colliderOne, const AABBCollider& colliderTwo);
bool Colliding(const AABBCollider& colliderOne, const SphereCollider& colliderTwo);
bool Colliding(const SphereCollider& colliderOne, const AABBCollider& colliderTwo);

我的想法是简单地遍历碰撞器 vector ,然后将每个碰撞器与列表中的所有其他碰撞器进行比较。

for (unsigned int a = 0; a < colliders.size(); ++a)
{
for (unsigned int b = a + 1; b < colliders.size(); ++b)
{
// Store the two colliders we're current comparing
std::shared_ptr<Collider> colliderOne = colliders[a];
std::shared_ptr<Collider> colliderTwo = colliders[b];

// Somehow cast pointers back to correct derived type

// Check colliding
if(Colliding(*colliderOneDerived, *colliderTwoDerived))
{
// Colliding
}

}
}

然而,要成功做到这一点,我需要将指针转换回正确的派生类型,以便调用正确的函数,但我不知道碰撞器每次都是什么类型。

基本碰撞器类有一个 Type() 函数,它从基本指针正确返回派生类型。

std::type_index Collider::Type() { return typeid(*this); }

有没有一种方法可以使用它来将指针转换为正确的派生类型?

最佳答案

你想做的是所谓的双重分派(dispatch),C++ 本身不支持它。以下是您可能会考虑的几个选项:

您可以使用虚函数来实现它,这意味着将采用每种类型的对象的虚函数添加到每个对象。这将导致相对快速的查找,但实现它的工作量呈二次方增长。

class Obj1;
class Obj2;

class Base{
virtual bool collide(Base* p ) =0;
virtual bool collide(Obj1*) = 0;
virtual bool collide(Obj2*) = 0;
};

class Obj1{
virtual bool collide(Base* p) override { return p->collide(this); }
virtual bool collide(Obj1* p) override { return colliding(p,this); }
virtual bool collide(Obj2* p) override;
};

class Obj2{
virtual bool collide(Base* p) override { return p->collide(this); }
virtual bool collide(Obj1* p) override { return colliding(p,this); }
virtual bool collide(Obj2* p) override { return colliding(p,this); }
};

bool Obj1::collide(Obj2* p) override { return colliding(p,this); }

您还可以使用 Visitor pattern几乎相同的效果。

您可以向返回对象的 typeid 的每个对象添加一个虚函数,并制作一个由一对 std::type_index 索引的函数指针的排序平面映射.这将提供更大的灵 active ,因为您可以在项目的多个位置向 map 添加对象。

您可以为每个对象添加一个唯一的 constexpr 索引,在每个对象中有一个返回该索引的虚函数,并制作一个元程序,该程序在编译时从对象列表中生成一个查找表。这几乎和我的第一个例子一样快,但只需要每个对象一个虚函数,并且所有对象类型在程序中的一个点都是已知的。用户将对索引的唯一性负责,但元程序可以检测到双重索引,从而减少错误的变化。

关于C++在不知道派生类的情况下将基类指针转换为派生类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28816005/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com