您可以将标准布局类对象地址转换为指向其第一个成员的指针,然后由后面的段落中的一个返回,这也经常在 C 中完成:
struct A { int x; };
A a;
// "px" is guaranteed to point to a.x
int *px = (int*) &a;
// guaranteed to point to a
A *pa = (A*)px;
为此,第一个成员和完整对象必须具有相同的地址(编译器无法通过任何字节调整 int 指针,因为它不知道它是否是 an 的成员A
)。
最后,如果多个组成类有数据成员,会出现什么问题?
在一个类中,成员按照声明顺序分配在递增的地址中。然而,C++ 并没有规定跨类的数据成员的分配顺序。如果派生类和基类都具有数据成员,则标准不会故意为它们的地址定义顺序,以便在布局内存时为实现提供充分的灵活性。但是要使上述演员表起作用,您需要知道分配顺序中的“第一个”成员是什么!
如果第一个数据成员也是基类会出现什么问题?
If the base class has the same type as the first data member, implementations that place the base classes before the derived class objects in memory would need to have a padding byte before the derived class object data members in memory (base class would have size one), to avoid having the same address for both the base class and the first data member (in C++, two distinct objects of the same type always have different addresses). But that would again make impossible to cast the address of the derived class object to the type of its first data member.