深度探索C++对象模型读书笔记(2)

时间:2021-09-06 21:50:03

以下测试平台均为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 \n", pd->*dmp );
} void func2( Device * pd )
{
int Base2::*dmp = &Base2::val3;
printf( "&Base::val3 = %p \n", dmp );
func1( dmp, pd );
} int main()
{
Device a;
a.val1 = ; a.val2 = ; a.val3 = ; a.val4 = ; a.vald = ;
func2( &a ); return ;
}

测试结果

深度探索C++对象模型读书笔记(2)

结论:编译器会自动转换父类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 \n", &Base1::val1 );
printf( "&Base1::val2 = %p \n", &Base1::val2 );
printf( "&Base2::val3 = %p \n", &Base2::val3 );
printf( "&Base2::val4 = %p \n", &Base2::val4 );
printf( "&Device::val1 = %p \n", &Device::val1 );
printf( "&Device::val2 = %p \n", &Device::val2 );
printf( "&Device::val3 = %p \n", &Device::val3 );
printf( "&Device::val4 = %p \n", &Device::val4 );
printf( "&Device::vald = %p \n", &Device::vald );
return ;
}

测试结果

深度探索C++对象模型读书笔记(2)

结论:继承的 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 \n", &Base1::val1 );
printf( "&Base1::val2 = %p \n", &Base1::val2 );
printf( "&Base2::val3 = %p \n", &Base2::val3 );
printf( "&Base2::val4 = %p \n", &Base2::val4 );
printf( "&Device::val1 = %p \n", &Device::val1 );
printf( "&Device::val2 = %p \n", &Device::val2 );
printf( "&Device::val3 = %p \n", &Device::val3 );
printf( "&Device::val4 = %p \n", &Device::val4 );
printf( "&Device::vald = %p \n", &Device::vald );
return ;
}

测试结果

深度探索C++对象模型读书笔记(2)

结论:虚拟继承的父类被存放于一张表中,以指针指向,因此vald的offset = sizeof(*p) = 4;