避免 dynamic_cast 向下转换为原始类型

Dan*_*Dan 5 c++ dynamic-cast

如何安全地向下转换(即在失败时返回 null)到基础对象的确切类型,而不会导致 的性能损失dynamic_cast,并且不必在我使用的每个类中放置支持代码?

Dan*_*Dan 4

dynamic_cast会遍历整个继承树,看看是否可以进行你想要的转换。如果您想要的只是直接向下转换为与对象相同的类型,并且不需要交叉转换、跨虚拟继承转换或转换为对象实际类型的基类的能力,请使用以下代码将工作:

template<class To>
struct exact_cast
{
    To result;

    template<class From>
    exact_cast(From* from)
    {
        if (typeid(typename std::remove_pointer<To>::type) == typeid(*from))
            result = static_cast<To>(from);
        else
            result = 0;
    }

    operator To() const
    {
        return result;
    }
};
Run Code Online (Sandbox Code Playgroud)

语义与其他强制转换运算符完全相同,即

Base* b = new Derived();
Derived* d = exact_cast<Derived*>(b);
Run Code Online (Sandbox Code Playgroud)

编辑:我已经在我正在从事的项目上对此进行了测试。我的结果QueryPerformanceCounter是:
dynamic_cast: 83,024,197
exact_cast:78,366,879
这是 5.6% 的加速。这适用于重要的 CPU 密集型代码。(它没有 I/O)

  • 有证据表明这比“dynamic_cast”更有效吗? (14认同)
  • 另外,为什么是类而不是函数? (5认同)
  • 在我的 4,000,000 次迭代测试中,此代码似乎比“dynamic_cast”快了 0.05 秒,在堆上构建多态对象并分配给基指针,强制转换为派生指针,然后取消分配它(使用“-Ofast”优化) gcc 4.7.1 的级别)。 (2认同)
  • @Nicol Bolas:这可能就是OP所说的“你想要的只是直接向下转换为与对象相同的类型”。“相同”应该意味着您只能向下转换为*最派生的对象类型*,而不是中间基础。当然,这极大地限制了该转换的可用性。 (2认同)