繁体   English   中英

C++ dynamic_cast dowcast 失败

[英]C++ dynamic_cast dowcast fails


在 C++ 中编写我的第一个大项目时,我遇到了一个单独使用谷歌和文档无法解决的问题。

我无法弄清楚为什么这个 dynamic_cast 会失败,即使 r 指向 MeshRenderer Object。

class MeshRenderer : public Component {...}
class Component : public GameObject {...}
class GameObject : protected TickEventConsumer, protected RenderEventConsumer, protected PhysicsTickEventConsumer {...}

class RenderEventConsumer 有一个虚方法,是 MeshRenderer 的基础。

 class MeshRenderer: public Component {...} class Component: public GameObject {...} class GameObject: protected TickEventConsumer, protected RenderEventConsumer, protected PhysicsTickEventConsumer {...}

根据 Visual Studio,r 的 vftable 是正确的。 在此处输入图像描述

PS:这是我关于stackoverflow的第一个问题,如果我违反了任何准则或缺少相关信息,请告诉我。

编辑:虽然我现在知道答案,但为了清楚起见,我用一个独立的例子重现了这个错误:

 #include <vector> #include <iostream> class RenderEventConsumer { virtual void onRender() {}; }; class RenderEventDispatcher { std::vector<RenderEventConsumer*> mConsumers; public: const std::vector<RenderEventConsumer*>& getConsumers() { return mConsumers; } void registerRenderEventConsumer(RenderEventConsumer* consumer) { mConsumers.push_back(consumer); } }; class GameObject: protected RenderEventConsumer {}; //changing this to public fixes dynamic_cast class Component: public GameObject {}; class MeshRenderer: public Component { public: void setup(RenderEventDispatcher& d) { d.registerRenderEventConsumer(this); } void onRender() override { } }; int main() { RenderEventDispatcher d; MeshRenderer* pt = new MeshRenderer(); pt->setup(d); for (RenderEventConsumer* r: d.getConsumers()) { MeshRenderer* m = dynamic_cast<MeshRenderer*>(r); if (m) { std::cout << "not nullptr\n"; } else { std::cout << "nullptr\n"; } } }

仅仅因为RenderEventConsumer是一个基础MeshRenderer ,这并不意味着从RenderEventConsumer派生的所有类也是(派生自) MeshRenderer

如果MeshRenderer不是指向 object 的动态类型(的基础),则dynamic_cast将返回 null。

这是如何发生的示例:

struct another_derived : RenderEventConsumer {} instance;
RenderEventConsumer* r = &instance;

// null, even through r is RenderEventConsumer*
dynamic_cast<MeshRenderer*>(r);

如果您发现需要使用dynamic_cast ,则意味着设计已损坏。 考虑使用例如访问者模式。

感谢 Kaldrr。
解决方案是从 RenderEventConsumer 公开派生。

class GameObject : public TickEventConsumer, public RenderEventConsumer, public PhysicsTickEventConsumer {...}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM