是从Derived <x> reinterpret_cast到Base <x>安全吗?</x> </x>

时间:2014-09-18 15:00:53

标签: c++ templates casting derived-class

考虑以下模板类。

template <typename X>
class Base
{
public:
    void method1() {...}
    void method2() {...}
    ...

private:
    int  member1;
    float member2;
    ...
};

template <typename X>
class Derived : public Base<X>
{
public:
    void m1() {...}
    void m2() {...}
// no members here
}

// similar with second set of classes SecBase, SecDerived

Base<SecBase<X>> originalObject;
Derived<SecDerived<X>>& wrapperRef = reinterpret_cast<Derived<SecDerived<X>>&>(originalObject);

这两个类具有完全相同的成员。 Derived类似于Base的包装。最后一行中的演员安全吗?如果我们考虑使用优化进行编译会怎样?编译器可以做一些它不会工作的优化吗?

2 个答案:

答案 0 :(得分:3)

  

最后一行的演员阵容安全吗?

如果两个类布局兼容,则转换有效;

  • 他们都有标准布局,如C ++ 11 9/7
  • 中所定义
  • 他们都有相同的非静态数据成员

看起来第一个条件得到满足;第二个是如果数据成员类型都不依赖于模板参数(或者,如果确实如此,它会解析为SecBase<X>SecDerived<X>的相同类型。)

话虽如此,我不会将其描述为&#34; safe&#34;,因为很容易修改代码并意外地破坏其中一个条件。

  

如果我们考虑使用优化进行编译会怎样?编译器可以做一些它不会工作的优化吗?

如果它们不是布局兼容的,那么程序有不确定的行为,你不能依赖任何东西。行为可能会根据优化或其他设置或月球的相位而改变。

答案 1 :(得分:1)

您应该为此重新设计解决方案,例如:

template <typename X>
class Derived
{
    Base* pB_;
public:
    Derived(Base * pB) : pB_(pB) {}
    void m1() {pB_->method1()}
    void m2() {pB_->method2()}
}