c – 是否会定义将实际基准转换为衍生的情况?
在一般情况下,它是(一个非常应得的)未定义行为从(动态)基础到推导类之一派生
明显的UB class Base { public: virtual void foo() { /* does something */} int a; } class Derived : public Base { public: virtual void foo() { /* does something different */} double b; } Base obj; Derived derObj = *static_cast<Derived *>(&obj); // <- here come the demons 在编译器的当前实现方法中,显然至少存在Vtable和b中包含垃圾值的值不一致的问题.所以在这些条件下,标准没有定义一个downcast的行为是有道理的. 不太明显的天真的情况 但是我很好奇知道在具体情况下是否有这样的规定呢? class Base { public: void foo() { /* does something */} int a = 1; double b = 2.; } class DerivedForInt : public Base { int getVal() { return a } } Base obj; DerivedForInt derObj = *static_cast<DerivedForInt *>(&obj); // <- still an UB ? 在这里我们可以很容易地想象编译器做正确的事情.但从标准的角度来看,还不清楚? 编辑:static_cast是用于说明目的的随机选择,如果与其他演员一起工作也很有意思! 解决方法
好的,我可能会为这个答案碎片
显然,正如其他答案所说,这是未定义的行为,如标准中所述.但是,如果您的Base类具有标准布局,并且DerivedForInt类不添加新数据成员,则它将具有相同的(标准)布局. 在这些条件下,即使是UB,你的演员也不应该出现任何麻烦.据其中一个消息来源,至少可以做到安全 DerivedForInt *derived = reinterpret_cast<DerivedForInt*>(&base.a); 资料来源: What are Aggregates and PODs and how/why are they special? PODs and inheritance in C++11. Does the address of the struct == address of the first member? 从第二个链接:
(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |