以下是布鲁斯·埃克尔的Thinking in C++(第1卷,第2版,第11章)在“指向成员的指针”标题下的一段:
...指针需要一个地址,但是类中没有“地址”;选择类成员意味着抵消该类。您不能生成实际地址,直到将该偏移量与特定对象的起始地址组合。指向成员的指针语法要求您在取消引用指向成员的指针的同时选择一个对象。
这句话是什么意思?我正在尝试做类似的事情:
&(objectname.member_variable)
我得到一个实际地址,例如0x22f14
,但是这个偏移量意味着距离起始地址有多远?
答案 0 :(得分:6)
我认为&(foo.bar)
只是一个指向变量的常规指针。通过说“指向成员的指针”,我们的意思是&(FooClass::bar)
,而不指定任何对象!注意,该值实际上可以在编译时计算并且可以用于例如在模板中。
成员指针的语法非常奇怪。
尝试运行以下代码:
#include <stdio.h>
class FooClass {
public:
int bar;
int bar2;
FooClass() : bar(0), bar2(0) {}
};
int main() {
//Showing what member pointers actually hold:
int FooClass::* barPtr=&FooClass::bar;
int FooClass::* bar2Ptr=&FooClass::bar2;
printf("barPtr=%p\nbar2Ptr=%p\n",barPtr,bar2Ptr);
//Showing how to use them:
FooClass foo;
foo.*bar2Ptr=42;
printf("foo={%d,%d}\n",foo.bar,foo.bar2);
}
您将获得输出:
barPtr=0x0
bar2Ptr=0x4
foo={0,42}
如您所见,两个值都保持成员从类开头的偏移量。即使您不知道您正在使用哪个对象,也可以计算它们。
但是如果你想取消引用它们,你必须提供一个对象 - 这就是.*
运算符的作用。
答案 1 :(得分:0)
是的,在这种情况下,术语 offset 表示该特定成员从该类的第一个成员(即对象位置)存储在内存中的距离。
结果得到的值是member * member_variable *的内存位置。仅出于可视化目的,如果您想知道偏移量(以字节为单位),您可以执行以下操作:
std::cout << reinterpret_cast<char *>(&(objectname.member_variable)) - reinterpret_cast<char *>(&objectname);