static_cast和RTTI vs dynamic_cast

时间:2012-09-25 17:40:33

标签: c++ dynamic-cast static-cast

请遵守以下代码。据我所知,dynamic_cast比static_cast慢。因为它在运行时评估类型。 我在这里的疑问是,如果我们将static_cast与typeid()一起使用如下,它是否需要与动态强制转换相同的时间? 它会比dynamic_cast更快吗?

class Shape
{ 
public:
  virtual ~Shape(){}
};
class Circle : public Shape{ };
class Square : public Shape{ };

使用RTTI进行静态转换:

Circle c;
Shape* s = &c; // Upcast: normal and OK

// More explicit but unnecessary:
s = static_cast<Shape*>(&c);
// (Since upcasting is such a safe and common
// operation, the cast becomes cluttering)

Circle* cp = 0;
Square* sp = 0;

// Static Navigation of class hierarchies
// requires extra type information:
if(typeid(s) == typeid(cp)) // C++ RTTI
    cp = static_cast<Circle*>(s);
if(typeid(s) == typeid(sp))
    sp = static_cast<Square*>(s);
if(cp != 0)
    cout << "It's a circle!" << endl;
if(sp != 0)
    cout << "It's a square!" << endl;

动态演员:

Circle c;
Shape* s = &c; // Upcast: normal and OK

s = &c;
Circle* cp = 0;
Square* sp = 0;
cp = dynamic_cast<Circle*>(s);
    if(cp != 0)
    cout << "It's a circle!" << endl;
sp = dynamic_cast<Square*>(s);
if(sp != 0)
    cout << "It's a square!" << endl;

4 个答案:

答案 0 :(得分:7)

测试类型然后执行static_cast会更快,但操作不等同,因为只允许向下转换为最派生类型(任何中间级别都不会与{{1]匹配}})。我会使用typeid,因为它更健壮(例如,如果有人扩展你的类型并传递指针,则不会中断)。

如果您的应用程序中dynamic_cast的性能存在问题,则应重新考虑该设计。虽然dynamic_cast + typeidstatic_cast快,但不必打开对象的运行时类型比任何一个都快。

答案 1 :(得分:3)

这些代码示例在逻辑上不相同。您忘记了dynamic_cast将类继承带入帐户,并且比较typeid()仅比较继承树的 leaf 部分。 typeid给你的唯一东西是“与该对象的实际类型相关的一些唯一标识符”。仅使用typeid(),您无法检查是否可以转换为公共库的指针,只能检查其运行时类型是否与运行时类型完全相同。

这样说,我认为static_cast + typeid在一般意义上应该更快,但在某些情况下会给出错误的答案。

答案 2 :(得分:1)

我认为任何体面的编译器都能够将两个示例优化为相同的代码。但是,找到答案的唯一方法是测量特定工具链的结果。

答案 3 :(得分:-1)

只有一种方法可以肯定。使用std :: chrono和high_resolution_clock进行测量。