多态C风格的演员有任何开销吗?

时间:2011-02-23 15:07:39

标签: c++ casting polymorphism

  • 是否将指向实例类的实例的指针强制转换为实例基类在C ++中是否有任何运行时开销,还是在编译时解析?

  • 如果确实有,那么在铸造操作中究竟需要计算什么?

示例:

class Foo;
class Bar : public Foo;

Bar* y = new Bar;
Foo* x = (Foo*) y;

(我知道我应该使用C ++风格的演员表,答案可能与他们相同)

4 个答案:

答案 0 :(得分:5)

Foo* x = (Foo*) y;

您无需将Bar*投射到Foo*。从派生到基础的铸造是隐含的:

Foo* x = y ; // is enough!

至于多态演员表,C风格演员表不等同于dynamic_cast。 C ++ dynamic_cast完全是一种添加到语言中的新功能,并且在C风格的演员表中没有匹配。

  

是否指向实例的指针   对于实例的一个衍生类   基类有任何运行时开销   在C ++中,还是解决了   编译时?

如果你像我上面那样做,那么在编译时解析从派生到基础的转换。所以它没有运行时开销。

答案 1 :(得分:5)

是的,虽然它可以忽略不计。

在这种情况下,C样式强制转换被解释为static_cast,这可能会导致指针调整。

struct Base {};

struct Derived: Base { virtual ~Derived(); } // note: introduced a virtual method

int main()
{
  Derived derived;
  Base* b = &derived;
  Derived* d = (Derived*) b;

  void* pb = b;
  void* pd = d;

  printf("%p %p", pb, pd);

  return 0;
}

只要基础子对象未与派生对象在同一地址对齐,就会发生此开销,这种情况发生在:

  • 介绍第一个虚拟方法
  • 使用多重继承

当然,指针调整通常被认为是可以忽略不计的,并且编译器应该足够聪明,如果不必要的话(消除0调整)就消除它。

注意:这是依赖于实现的,不是标准

强制要求的

答案 2 :(得分:2)

C强制转换没有任何运行时开销。创建运行时开销的唯一强制转换操作是dynamic_cast<>(),因为它检查运行时类型信息。

答案 3 :(得分:1)

查看类似问题的答案:regular cast vs static cast vs dynamic cast

总结:C样式的强制转换没有运行时开销,因为它尝试了除dynamic_cast之外的一堆C ++强制转换方法(会导致运行时惩罚)。