通常,指针包含地址。为什么指向类成员的指针包含偏移量?
讨论类data成员的指针,而不是成员函数的指针。
指向类成员的指针与常规指针的不同之处在于,它本身实际上并不指向内存中的单个位置。例如,如果您有此设置:
struct MyStruct {
int x;
int y;
};
int MyStruct::* ptr = &MyStruct::y;
然后,指针ptr
实际上没有指向内存地址,因为没有一个对象MyStruct::y
。相反,MyStruct
的每个实例都有其自己的数据成员y
的副本。
C ++标准没有规定如何实际实现成员指针,但是一种常见的策略是使成员指针存储从对象的基址到所讨论字段的字节偏移量。这样,当您编写类似
的内容时MyStruct ms;
ms.*ptr = 137;
编译器可以生成代码:“转到ms
的基地址,向前跳过由ptr
中存储的值指定的多个字节,然后写入137。”
指针不必包含地址。指针是间接访问特定对象的工具-即编写将访问在编译时未知的对象的代码。示例:
a = 10; // It is known at compile time, 10 is written to object a
*pi = 10; // It is not known at compile time where 10 is written to
对于普通对象,在指针中具有地址是实现此目标的最便宜的方法(但是,对于C ++脚本而言,情况并非如此!]]
但是,对于成员来说,普通地址是行不通的-没有类的成员地址!只有拥有类对象时,您才能知道成员的物理地址。
因此,您必须使用某种偏移量,一旦知道实际对象,就可以将其转换为物理地址。
指向成员的指针不是指针。
在C ++类中,成员与其各自的类密切相关。因此,指向成员的指针的声明始终包含其所属的类。如果这导致指向存储在指针中的类实例的偏移量或未指定其他内容。