关于C++数据成员指针的困惑:为何输出均为1?
为什么&Foo::a和&Foo::b输出都是1?
这个问题的核心其实不是成员指针的偏移量逻辑错了,而是**cout处理成员指针的方式和你想的不一样**。先看你的代码:
class Foo { public: int a = 1; int b = 2; }; int main() { Foo foo; cout << &Foo::a << endl;//output 1 cout << &Foo::b << endl;//also output 1 }
首先,成员指针的本质
你说的完全没错:非静态数据成员指针存储的确实是相对于对象起始地址的偏移量。比如&Foo::a的偏移量应该是0(它是类的第一个成员),&Foo::b的偏移量通常是4(假设int占4字节)。
问题出在cout的输出逻辑
cout的operator<<并没有专门针对int Foo::*(成员指针类型)的重载。当你尝试输出成员指针时,C会触发隐式类型转换:根据C标准,任何非空的成员指针都可以转换为bool类型的true,空成员指针则转换为false。
而cout输出bool类型的值时,默认行为是用1代表true、0代表false。所以不管是&Foo::a还是&Foo::b,都是非空的成员指针,都会被转换成true,最终输出结果自然都是1。
如何输出真正的偏移量?
如果想看到成员指针实际存储的偏移量,你可以用reinterpret_cast把它转换成整数类型(比如ptrdiff_t):
#include <iostream> #include <cstddef> // 包含ptrdiff_t的定义 using namespace std; class Foo { public: int a = 1; int b = 2; }; int main() { cout << reinterpret_cast<ptrdiff_t>(&Foo::a) << endl; // 输出0 cout << reinterpret_cast<ptrdiff_t>(&Foo::b) << endl; // 输出4(取决于int的实际大小) }
这样就能得到你预期的偏移量结果了。
内容的提问来源于stack exchange,提问作者J.zhou
相关产品推荐
相关产品推荐

