是否将指向实例类的实例的指针强制转换为实例基类在C ++中是否有任何运行时开销,还是在编译时解析?
如果确实有,那么在铸造操作中究竟需要计算什么?
示例:
class Foo;
class Bar : public Foo;
Bar* y = new Bar;
Foo* x = (Foo*) y;
(我知道我应该使用C ++风格的演员表,答案可能与他们相同)
答案 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 ++强制转换方法(会导致运行时惩罚)。