给定一个foo
类型的变量和该类中FooClass*
的成员变量命名bar
,是在任何具有一些约束的情况下的距离foo
和&(foo->bar)
相同的距离:
FooClass
是非POD类型.
我们知道它foo
总是指向一个实例FooClass
,而不是它的某个子类型.
我们只关心单个编译器和单个编译的行为; 也就是说,在gcc下可能导致的值从未在使用MSVC编译的代码中使用,并且永远不会保存以便在编译之间重复使用.它以二进制计算并在二进制文件中使用,就是这样.
我们不使用自定义new
,尽管该类的某些实例可能是堆栈分配的,而是一些堆分配的.
没有明确ctor
的FooClass
; 它依赖于编译器生成的一个(并且每个字段FooClass
都是POD或默认构造的).
我无法在标准中找到这方面的保证(我也没想到),但是我用gcc进行的基本测试让我相信它总会如此.我也知道这个保证是针对POD类型的,但我们假设这种类型不能是POD.
更新/澄清:这仅适用于单个二进制文件的单个编译; 计算出的偏移量永远不会离开那一次执行.基本上,我希望能够在静态地图中唯一地标识类的字段,然后能够在某个宏/模板/ EVIL欺骗中查找该映射.这仅仅是为了我自己的娱乐,没有生命支持机器会依赖这个代码.
编译完程序后,是*.
偏移量将保持不变.
但是有一个非常重要的限制: foo必须专门指向FooClass对象.不是从FooClass派生的类,或其他任何东西.
C++使成员偏移的POD区别的原因是因为多重继承和vtable指针的位置(或缺少)可能会创建一个对象的地址与该对象的基地址不同的情况.