c++ - C++ 正在转换一个reinterpret_cast派生的类指针到基类指针未定义行为?

  显示原文与译文双语对照的内容

请看下面的简单示例:


struct Base {/* some virtual functions here */};


struct A: Base {/* members, overridden virtual functions */};


struct B: Base {/* members, overridden virtual functions */};



void fn() {


 A a;


 Base *base = &a;


 B *b = reinterpret_cast<B *>(base);


 Base *x = b;


//use x here, call virtual functions on it


}



这个小Fragment有未定义的行为?

reinterpret_cast 定义良好,它返回的base 值不变,只使用 B *的类型。

但我不确定 Base *x = b; 它使用 b,它有一个 B * 类型,但它实际上指向一个 A 对象。 我不确定 x 是否是"正确" base 指针,是否可以用它来调用虚函数。

时间:

static_cast ( 或者隐式derived-to-base-pointer转换,它完全一样) 与 reinterpret_cast 有很大区别。 不能保证基子对象以与完整对象相同的地址开始。

大多数实现在同一个地址中放置第一个子对象,但是这样的实现甚至不能在同一个地址中放置两个不同的非空 基子对象。 ( 具有虚函数的对象不是空的) 。 当基子对象与完整对象不同时,static_cast 不是一个 op,它包含指针调整。

有些实现甚至不会将第一个基子对象放置在与完整对象相同的地址。 它允许在派生的所有成员之后放置基子对象,例如。 IIRC C++ 编译器用于以这种方式对类进行布局。 在这样的实现中,几乎保证了这里代码失败。

具有多个基础的类似代码在许多实现中都会失败。 示例

...