以下测试平台均为vs 2012
指向Data Member的指针测试(1)
#include <stdio.h> class Base1 { public: int val1; int val2; }; class Base2 { public: int val3; int val4; }; class Device : public Base1, public Base2 { public: int vald; }; void func1( int Device::*dmp, Device * pd ) { printf( "Device::val3 = %d ", pd->*dmp ); } void func2( Device * pd ) { int Base2::*dmp = &Base2::val3; printf( "&Base::val3 = %p ", dmp ); func1( dmp, pd ); } int main() { Device a; a.val1 = 1; a.val2 = 2; a.val3 = 3; a.val4 = 4; a.vald = 5; func2( &a ); return 0; }
测试结果
结论:编译器会自动转换父类member的offset
指向Data Member的指针测试(2)
#include <stdio.h> class Base1 { public: int val1; int val2; }; class Base2 { public: int val3; int val4; }; class Device : public Base1, public Base2 { public: int vald; }; int main() { printf( "&Base1::val1 = %p ", &Base1::val1 ); printf( "&Base1::val2 = %p ", &Base1::val2 ); printf( "&Base2::val3 = %p ", &Base2::val3 ); printf( "&Base2::val4 = %p ", &Base2::val4 ); printf( "&Device::val1 = %p ", &Device::val1 ); printf( "&Device::val2 = %p ", &Device::val2 ); printf( "&Device::val3 = %p ", &Device::val3 ); printf( "&Device::val4 = %p ", &Device::val4 ); printf( "&Device::vald = %p ", &Device::vald ); return 0; }
测试结果
结论:继承的 member直接存放在Device中,因此vald的offset = sizeof(Base1) + sizeof(Base2) = 8 + 8 = 0x10;
指向Data Member的指针测试(3)
#include <stdio.h> class Base1 { public: int val1; int val2; }; class Base2 { public: int val3; int val4; }; class Device : virtual public Base1, virtual public Base2 { public: int vald; }; int main() { printf( "&Base1::val1 = %p ", &Base1::val1 ); printf( "&Base1::val2 = %p ", &Base1::val2 ); printf( "&Base2::val3 = %p ", &Base2::val3 ); printf( "&Base2::val4 = %p ", &Base2::val4 ); printf( "&Device::val1 = %p ", &Device::val1 ); printf( "&Device::val2 = %p ", &Device::val2 ); printf( "&Device::val3 = %p ", &Device::val3 ); printf( "&Device::val4 = %p ", &Device::val4 ); printf( "&Device::vald = %p ", &Device::vald ); return 0; }
测试结果
结论:虚拟继承的父类被存放于一张表中,以指针指向,因此vald的offset = sizeof(*p) = 4;