This holds only true if your class is of standard_layout type. This you can test using the type trait is_standard_layout
std::cout << std::is_standard_layout<A>::value << '
';
std::cout << std::is_standard_layout<B>::value << '
';
For other classes, you have additional information stored in memory, which is compiler specific and not standardized. You can have a look at This question where some memory layouts are discussed and showed.
For your second example/question the standard has the following quote (5.2.10/7, N3337 draft):
An object pointer can be explicitly converted to an object pointer of a different type. When a prvalue v of type “pointer to T1” is converted to the type “pointer to cv T2”,
the result is static_cast(static_cast(v)) if both T1 and T2 are standard-layout types (3.9) and the alignment requirements of T2 are no stricter than those of T1,
or if either type is void. Converting a prvalue of type“pointer to T1” to the type “pointer to T2” (where T1 and T2 are object types and where the alignment requirements of T2 are
no stricter than those of T1) and back to its original type yields the original pointer value. The result of any other such pointer conversion is unspecified.
If i read and interpret this correctly, then your example is unspecified, as the alignment requirements of A are bigger that those of B. However, the other way should be ok, e.g:
int main()
{
A *pa=new A();
B *pb=reinterpret_cast<B*>(pa);
pb->x++;
std::cout << pa->a;
}
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…