根据ABI ,
A pointer to data member is an offset from the base address of the class object containing it... A NULL pointer is represented as -1
但是,根据 c++ 标准(我有修订版 4296,它位于 4.11/1 中),
the null member pointer value of that type ... is distinguishable from any pointer to member not created from a null pointer constant
和-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
}
在此代码中,我的编译器(x86_64-linux-gnu 上的 g++4.9.2)放置 h
在 A
的最后一个字节、和地点 B
就在A
之后在C
。因此,C::A::h
的偏移量从C::B
的基地址开始是-1。
(转换是合法的,其结果可以用于动态类型 C 的对象,即使其静态类型是 B。标准表示 (5.2.9/12)“尽管B 类不需要包含原始成员,通过指向成员的指针执行间接操作的对象的动态类型必须包含原始成员”)
我误解了什么?
(我怀疑我的误解是关于短语“包含原始成员的类”(5.2.9/12) - 考虑到 C::h
,该短语可能指的是 A
和不是 C
,但标准明确指出(10/2)“基类的成员也被视为派生类的成员”)
最佳答案
[expr.static.cast]/p12:
A prvalue of type “pointer to member of
D
of type cv1T
” can be converted to a prvalue of type “pointer to member ofB
” of type cv2T
, whereB
is a base class (Clause 10) ofD
, [...]. If classB
contains the original member, or is a base or derived class of the class containing the original member, the resulting pointer to member points to the original member. Otherwise, the behavior is undefined.
“包含原始成员的类”是A
。 B
不是 A
的基类或派生类,因此行为未定义。
关于c++ - 有效的成员指针可以与 NULL 指针具有相同的值吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32672876/