Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/128.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 指向成员的有效指针能否与空指针具有相同的值?_C++_Standards_Language Lawyer_Abi_Pointer To Member - Fatal编程技术网

C++ 指向成员的有效指针能否与空指针具有相同的值?

C++ 指向成员的有效指针能否与空指针具有相同的值?,c++,standards,language-lawyer,abi,pointer-to-member,C++,Standards,Language Lawyer,Abi,Pointer To Member,根据, 指向数据成员的指针是与数据成员的基址的偏移量 包含它的类对象。。。空指针表示为-1 但是,根据C++标准(我有修订4296,并且在 4.11 / 1 < /强>)中, 该类型的空成员指针值。。。可分辨 从任何指针到不是从空指针常量创建的成员 和-1可以是有效的偏移量 考虑这种情况: #include <iostream> using namespace std; struct A { char a,b,c,d,e,f,g,h; }; struct B {

根据,

指向数据成员的指针是与数据成员的基址的偏移量 包含它的类对象。。。空指针表示为-1

但是,根据C++标准(我有修订4296,并且在<强> 4.11 / 1 < /强>)中,

该类型的空成员指针值。。。可分辨 从任何指针到不是从空指针常量创建的成员

和-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
}
#包括
使用名称空间std;
结构A{
字符a、b、c、d、e、f、g、h;
};
结构B{
int i;
};
结构C:A,B{};
int main(){
字符C::*p=&C::h;
字符B::*q=静态_转换(p);

cout[expr.static.cast]/p12:

cv1
T
类型的“指向
D
成员的指针”类型的PR值可转换为cv2类型的“指向
B
成员的指针”类型的PR值
T
,其中
B
D
的基类(第10条),[…]如果类
B
包含原始成员,或是基类或 衍生 包含原始成员的类的类,结果 指向成员的指针指向原始成员。否则 行为是未定义的


“包含原始成员的类”is
A
B
不是
A
的基类或派生类,因此行为是未定义的。

你错了,从基址偏移-1是不可能的。对象的基址是完整对象的地址,而不是该完整对象内子对象的地址。

你的
静态转换
废话。您正在向<>代码> b::*/> >,即指向<代码> b >代码>的成员。但是,P中存储的成员实际上没有指向<代码> b>代码>的成员。因此,欢迎使用未定义的行为字段。规范的t好像是三次。它真的很复杂。下一个猜测是:你引用了两个不同的文档。也许ABI和标准在这方面不兼容。为什么不能将
C
视为那个类呢?它也包含
i
。@asaelr你能想出一个
静态转换
有未定义的行为吗或者根据该解读?不,但它不会影响该句的意思。@asaelr,但它会;因为委员会不太可能在标准中写一个完全没有意义的句子(自焚笑话除外),一个解释会使一些东西变得毫无意义,不太可能反映委员会的意图。如果我理解正确,你会说,即使我的代码根据委员会编写的内容是有效的,但根据他们的意思是无效的。因为我不是一个标准阅读专家,这可能是我能得到的最好答案,我将接受它。该标准明确允许将派生::*转换为基::*,在这种情况下,基地址将是子对象的地址。