深度探索C++對象模型讀書筆記(2)

如下測試平臺均爲vs 2012測試

指向Data Member的指針測試(1)spa

#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 = 1; a.val2 = 2; a.val3 = 3; a.val4 = 4; a.vald = 5;
    func2( &a );

    return 0;
}

測試結果3d

結論:編譯器會自動轉換父類member的offset指針

 

指向Data Member的指針測試(2)code

#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 0;
}

測試結果blog

結論:繼承的 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 0;
}

測試結果io

結論:虛擬繼承的父類被存放於一張表中,以指針指向,所以vald的offset = sizeof(*p) = 4;編譯

相關文章
相關標籤/搜索