根据ABI,
指向数据成员的指针是与基地址的偏移量 包含它的类对象... NULL指针表示为-1
但是,根据c ++标准(我有修订版4296,并且 4.11 / 1 ),
该类型的null成员指针值是可区分的 从任何指向未使用空指针常量
创建的成员的指针
和-1可以是有效的偏移量。
考虑这种情况:
#include <iostream>
using namespace std;
struct A {
char a,b,c,d,e,f,g,h;
};
struct B {
int i;
};
struct C : A,B {};
int main() {
char C::*p=&C::h;
char B::*q = static_cast<char B::*>(p);
cout<< (q==nullptr) <<endl; //prints 1
}
在这段代码中,我的编译器(x ++ 4.9.2 on x86_64-linux-gnu)将h
放在A
的最后一个字节,然后将B
放在后面A
中的C
。因此,C::A::h
与基地址C::B
的偏移量为-1。
(转换是合法的,其结果可用于动态类型C的对象,即使其静态类型为B.标准说明( 5.2.9 / 12 )&# 34;虽然B类不需要包含原始成员,但是通过指向成员的指针间接的对象的动态类型必须包含原始成员&#34;)
我误解了什么?
(我怀疑我的误解是关于短语&#34;包含原始成员的课程&#34;( 5.2.9 / 12 ) - 考虑C::h
,该短语可以参考A
而不是C
,但标准明确说明( 10/2 )&#34;基类的成员也被视为成员派生类&#34;)