根据严格别名规则:
struct B { virtual ~B() {} };
struct D : public B { };
D d;
char *c = reinterpret_cast<char*>(&d);
任何类型的对象都可以转换成
char*
,但现在的问题是,它是否会指向&d的相同地址?C++标准保证它将返回相同的地址。根据严格别名规则:
struct B { virtual ~B() {} };
struct D : public B { };
D d;
char *c = reinterpret_cast<char*>(&d);
char*
,但现在的问题是,它是否会指向&d的相同地址?C++标准保证它将返回相同的地址。c
和 &d
确实具有相同的值,如果你重新解释将 c
转换为 D*
,你会得到一个有效的指针,可以对其进行解引用。此外,你可以将 c
视为(指向数组 char[sizeof(D)]
的第一个元素的)不透明数组 - 这确实是将指针转换为 char 指针的主要目的:允许序列化和反序列化(例如 ofile.write(c, sizeof(D));
),但通常只应对基本类型(及其数组)执行此操作,因为复合类型的二进制布局通常无法以可移植的方式指定。reinterpret_cast<char*>(static_cast<B*>(&d))
可以被视为一个不透明数组 char[sizeof(B)]
。意图很明确(不需要争论):
reinterpret_cast
永远不会改变地址的值,除非目标类型不能表示所有地址值(例如小整数类型,在具有内在对齐的指针类型上:例如只能表示偶地址的指针,或者对象指针和函数指针不能混合使用...)。
标准措辞未能捕捉到这一点,但这并不意味着这里存在真正的实际问题。
char *c = reinterpret_cast<char*>(&d);
c
将始终指向 d
的第一个字节。