c++ 中的 dynamic_cast 有啥替代方法吗?

Posted

技术标签:

【中文标题】c++ 中的 dynamic_cast 有啥替代方法吗?【英文标题】:Is there any alternative to dynamic_cast in c++?c++ 中的 dynamic_cast 有什么替代方法吗? 【发布时间】:2019-10-24 18:13:13 【问题描述】:

如果 RTTI 在某些编译器环境中被禁用,我想知道这一点。

用例:

我在我的代码中使用了它,它在我的机器上运行,但在集成测试期间,代码无法正常运行,而是崩溃了。

我认为如果 RTTI 不存在,它会返回 null,这在我的代码中已处理,但行为出乎意料。

我应该检查什么才能优雅地终止它?

此外,当我使用 dynamic_cast 的包装器(在我们的内部框架中定义)时,它工作得很好。该包装器需要什么样的实现来满足这个要求?

【问题讨论】:

This gist shows how to detect whether RTTI is enabled. 也许你应该发布代码和编译器信息。你dynamic_cast是指针还是引用? 使用virtual函数试过被拒绝了? 如果 RTTI 被禁用,你希望 dynamic_cast 有什么行为? @M.M:我想要一些功能相似但没有 RTTI 的东西。我发现,我们有一些内部专有框架可以做到这一点。我想虽然这里提供的解决方案非常优雅,但没有这样的选择。谢谢。 【参考方案1】:

Raymond Chen 在评论中留下了精彩的 link 关于如何检测 RTTI 是否启用的评论。

要完成此操作,您可以使用以下命令覆盖 dynamic_cast

#if !defined(RTTI_ENABLED)
    #define dynamic_cast _NullPtrTFn
#endif

template <typename T1, typename T2>
T1* _NullPtrTFn(T2* p)

    static_cast<T1*>(p); // try fail to compile (https://godbolt.org/z/hcjKki)
    return static_cast<T1*>(nullptr);

【讨论】:

这和#define dynamic_cast static_cast有区别吗? @M.M 是的,因为 1) 如果您尝试向下转换,static_cast 会引发编译错误 2) 在向上转换的情况下,它不会返回 nullptr "如果你尝试向下转换,static_cast 会抛出编译错误" - 不正确 这如何编译?真正的dynamic_cast只有1个模板参数,而_NullPtrTFn有2个,所以当RTTI_ENABLED未定义时,不应该使用dynamic_cast&lt;T&gt;编译失败吗?我认为像template &lt;typename T&gt; T* _NullPtrTFn(void*) return nullptr; 这样的实现会更好,是吗? @tuket 好吧,我想我没有考虑到Template Argument Deduction。谢谢。

以上是关于c++ 中的 dynamic_cast 有啥替代方法吗?的主要内容,如果未能解决你的问题,请参考以下文章

有啥好的 C++ 项目构建工具可以替代 make 吗? [关闭]

C++中的new/delete构造/析构函数dynamic_cast分析

C++强制类型转换操作符 dynamic_cast

C++:即使转换的对象不是 NULL,dynamic_cast 也会导致 SEGFAULT。怎么会这样?

const_cast,static_cast,dynamic_cast,reinterpret_cast的区别

dynamic_cast 与 typeid