简单研究C++ 对象内存布局

关于C++对象布局 看了大佬的博客,大佬的博客过于久远格式比较清奇,我整理了,顺便改了程序能够在 64位机运行。

单一的一般继承

在这里插入图片描述
通俗的讲,一层层下去。

#include<iostream>
using namespace std;

class Parent
{
public:
    long iparent;//因为是64位机,所以改成了 long 
    
    Parent() : iparent(10) {}
    virtual void f() { cout << " Parent::f()" << endl; }
    virtual void g() { cout << " Parent::g()" << endl; }
    virtual void h() { cout << " Parent::h()" << endl; }
};

class Child : public Parent
{
public:
    long ichild;
    Child() : ichild(100) {}
    virtual void f() { cout << "Child::f()" << endl; }
    virtual void g_child() { cout << "Child::g_child()" << endl; }
    virtual void h_child() { cout << "Child::h_child()" << endl; }
};
class GrandChild : public Child
{
public:
    long igrandchild;
    GrandChild() : igrandchild(1000) {}
    virtual void f() { cout << "GrandChild::f()" << endl; }
    virtual void g_child() { cout << "GrandChild::g_child()" << endl; }
    virtual void h_grandchild() { cout << "GrandChild::h_grandchild()" << endl; }
};
typedef void (*Fun)(void);
int main()
{

    GrandChild gc;
    long **pVtab = (long **)&gc;
    Fun pFun;
    cout << "[0] GrandChild::_vptr->" << endl;
    for (int i = 0; (Fun)pVtab[0][i] != NULL; i += 2)
    {
        pFun = (Fun)pVtab[0][i];
        cout << "    [" << i << "] ";
        pFun();
    }
    printf("start offet:%llx\n", pVtab);
    cout << "[1] Parent.iparent = " << (long)((pVtab[1])) << endl;
    cout << "[2] Child.ichild = " << (long)(pVtab[2]) << endl;
    cout << "[3] GrandChild.igrandchild = " << (long)(pVtab[3]) << endl;
}

输出结果

[0] GrandChild::_vptr->
    [0] GrandChild::f()
    [2]  Parent::h()
    [4] Child::h_child()
start offet:7ffee4956f80
[1] Parent.iparent = 10
[2] Child.ichild = 100
[3] GrandChild.igrandchild = 1000

在这里插入图片描述

顺便我们用gdb 看一下。

GNU gdb (Debian 7.12-6) 7.12.0.20161007-git
list
40	    {
41	        pFun = (Fun)pVtab[0][i];
42	        cout << "    [" << i << "] ";
43	        pFun();
44	    }
45	    printf("start offet:%llx\n", pVtab);
46	    cout << "[1] Parent.iparent = " << (long)((pVtab[1])) << endl;
47	    cout << "[2] Child.ichild = " << (long)(pVtab[2]) << endl;
48	    cout << "[3] GrandChild.igrandchild = " << (long)(pVtab[3]) << endl;
49	}

p pVtab
$1 = (long **) 0x7fffffffcb90

x /10xg 0x7fffffffcb90
0x7fffffffcb90:	0x0000555555755ce0(你可以继续找下去可以找到具体函数地址)	0x000000000000000a(10)
0x7fffffffcba0:	0x0000000000000064(100)	0x00000000000003e8(1000)
0x7fffffffcbb0:	0x000000000000008e	0x000055555555509a
0x7fffffffcbc0:	0x00007fffffffcb90	0x0000000655554bf0
0x7fffffffcbd0:	0x00007fffffffccc0	0x0000000000000000

多重继承

在这里插入图片描述

#include<iostream>
using namespace std;
class Base1
{
public:
    long ibase1;
    Base1() : ibase1(0x10) {}
    virtual void f() { cout << "Base1::f()" << endl; }
    virtual void g() { cout << "Base1::g()" << endl; }
    virtual void h() { cout << "Base1::h()" << endl; }
};
class Base2
{
public:
    long ibase2;
    Base2() : ibase2(0x20) {}
    virtual void f() { cout << "Base2::f()" << endl; }
    virtual void g() { cout << "Base2::g()" << endl; }
    virtual void h() { cout << "Base2::h()" << endl; }
};
class Base3
{
public:
    long ibase3;
    Base3() : ibase3(0x30) {}
    virtual void f() { cout << "Base3::f()" << endl; }
    virtual void g() { cout << "Base3::g()" << endl; }
    virtual void h() { cout << "Base3::h()" << endl; }
};
class Derive : public Base1,
               public Base2,
               public Base3
{
public:
    long iderive;
    Derive() : iderive(0x100) {}
    virtual void f() { cout << "Derive::f()" << endl; }
    virtual void g1() { cout << "Derive::g1()" << endl; }
};
typedef void (*Fun)(void);
int main()
{
    Derive d;
    long **pVtab = (long **)&d;
    Fun pFun;
    cout<<hex;
    cout << "[0] Base1::_vptr->" << endl;
    pFun = (Fun)pVtab[0][0];
    cout << "     [0] ";
    pFun();
    pFun = (Fun)pVtab[0][1];
    cout << "     [1] ";
    pFun();
    pFun = (Fun)pVtab[0][2];
    cout << "     [2] ";
    pFun();
    pFun = (Fun)pVtab[0][3];
    cout << "     [3] ";
    pFun();
    pFun = (Fun)pVtab[0][4];
    cout << "     [4] ";
    cout << pFun << endl;
    cout << "[1] Base1.ibase1 = " << (long)(pVtab[1]) << endl;
    long s = sizeof(Base1) / 8;
    cout << "[" << s << "] Base2::_vptr->" << endl;
    pFun = (Fun)pVtab[s][0];
    cout << "     [0] ";
    pFun();
    cout << "     [1] ";
    pFun=(Fun)pVtab[s][1];
    pFun();
    pFun = (Fun)pVtab[s][2];
    cout << "     [2] ";
    pFun();
    pFun = (Fun)pVtab[s][3];
    cout << "     [3] ";
    cout << pFun << endl;
    cout << "[" << s + 1 << "] Base2.ibase2 = " << (long)(pVtab[s + 1]) << endl;
    s = s + sizeof(Base2) / 8;
    cout << "[" << s << "] Base3::_vptr->" << endl;
    pFun = (Fun)pVtab[s][0];
    cout << "     [0] ";
    pFun();
    pFun = (Fun)pVtab[s][1];
    cout << "     [1] ";
    pFun();
    pFun = (Fun)pVtab[s][2];
    cout << "     [2] ";
    pFun();
    pFun = (Fun)pVtab[s][3];
    cout << "     [3] ";
    cout << pFun << endl;
    s++;
    cout << "[" << s << "] Base3.ibase3 = " << (long)pVtab[s] << endl;
    s++;
    cout << "[" << s << "] Derive.iderive = " << (long)pVtab[s] << endl;
}

运行结果

[0] Base1::_vptr->
     [0] Derive::f()
     [1] Base1::g()
     [2] Base1::h()
     [3] Derive::g1()
     [4] 1//这个表示最后一个
[1] Base1.ibase1 = 10
[2] Base2::_vptr->
     [0] Derive::f()
     [1] Base2::g()
     [2] Base2::h()
     [3] 1
[3] Base2.ibase2 = 20
[4] Base3::_vptr->
     [0] Derive::f()
     [1] Base3::g()
     [2] Base3::h()
     [3] 0
[5] Base3.ibase3 = 30
[6] Derive.iderive = 100

用GDB看看

-exec p pVtab
$1 = (long **) 0x7fffffffcb80

-exec x /10xg 0x7fffffffcb80
0x7fffffffcb80:	0x0000555555756c50	0x0000000000000010
0x7fffffffcb90:	0x0000555555756c80	0x0000000000000020
0x7fffffffcba0:	0x0000555555756ca8	0x0000000000000030
0x7fffffffcbb0:	0x0000000000000100	0x0000000000000000
0x7fffffffcbc0:	0x000055555555583e	0x00007fffffffcb80

-exec x /10xg 0x0000555555756c50
0x555555756c50 <_ZTV6Derive+16>:	0x000055555555583e	0x00005555555555be
0x555555756c60 <_ZTV6Derive+32>:	0x00005555555555f6	0x0000555555555882
0x555555756c70 <_ZTV6Derive+48>:	0xfffffffffffffff0	0x0000555555756d38
0x555555756c80 <_ZTV6Derive+64>:	0x000055555555587b	0x000055555555568c
0x555555756c90 <_ZTV6Derive+80>:	0x00005555555556c4	0xffffffffffffffe0

-exec x /10xg 0x000055555555583e (不知道为啥其他查看其他几个虚表,和这个值不一样,但是也指向这个函数)
0x55555555583e <Derive::f()>:	0x10ec8348e5894855	0x57358d48f87d8948
0x55555555584e <Derive::f()+16>:	0x18083d8d48000001	0x48fffff453e80020
0x55555555585e <Derive::f()+32>:	0x201791058b48c289	0xe8d78948c6894800
0x55555555586e <Derive::f()+48>:	0x48c3c990fffff45e	0xef8348c3eb20ef83
0x55555555587e <_ZThn16_N6Derive1fEv+3>:	0xe589485590bdeb10	0xf87d894810ec8348

在这里插入图片描述

重复继承

在这里插入图片描述

#include <iostream>
using namespace std;
class B
{
public:
    long ib;
    char cb;

public:
    B() : ib(0), cb('B')
    {
    }

    virtual void
    f()
    {
        cout << "B::f()" << endl;
    }
    virtual void Bf() { cout << "B::Bf()" << endl; }
};

class B1 : public B
{
public:
    long ib1;
    char cb1;

public:
    B1() : ib1(11), cb1('1')
    {
    }
    virtual void
    f()
    {
        cout << "B1::f()" << endl;
    }
    virtual void f1() { cout << "B1::f1()" << endl; }
    virtual void Bf1() { cout << "B1::Bf1()" << endl; }
};

class B2 : public B
{
public:
    long ib2;
    char cb2;

public:
    B2() : ib2(12), cb2('2')
    {
    }
    virtual void
    f()
    {
        cout << "B2::f()" << endl;
    }
    virtual void f2() { cout << "B2::f2()" << endl; }
    virtual void Bf2() { cout << "B2::Bf2()" << endl; }
};

class D : public B1,
          public B2
{
public:
    long id;
    char cd;

public:
    D() : id(100), cd('D')
    {
    }
    virtual void
    f()
    {
        cout << "D::f()" << endl;
    }
    virtual void f1() { cout << "D::f1()" << endl; }
    virtual void f2() { cout << "D::f2()" << endl; }
    virtual void Df() { cout << "D::Df()" << endl; }
};

typedef void (*Fun)(void);
int main()
{
    long **pVtab = NULL;

    Fun pFun = NULL;

    D d;

    pVtab = (long **)&d;

    cout << "[0] D::B1::_vptr->" << endl;

    pFun = (Fun)pVtab[0][0];

    cout << "   [0] ";
    pFun();

    pFun = (Fun)pVtab[0][1];

    cout << "   [1] ";
    pFun();

    pFun = (Fun)pVtab[0][2];

    cout << "   [2] ";
    pFun();

    pFun = (Fun)pVtab[0][3];

    cout << "   [3] ";
    pFun();

    pFun = (Fun)pVtab[0][4];

    cout << "   [4] ";
    pFun();

    pFun = (Fun)pVtab[0][5];

    cout << "   [5] 0x" << pFun << endl;

    cout << "[1] B::ib = " << (long)pVtab[1] << endl;

    cout << "[2] B::cb = " << static_cast<char>((long)(pVtab[2])) << endl;

    cout << "[3] B1::ib1 = " << (long)pVtab[3] << endl;

    cout << "[4] B1::cb1 = " << (static_cast<char>((long)(pVtab[4]))) << endl;

    cout
        << "[5] D::B2::_vptr->" << endl;

    pFun = (Fun)pVtab[5][0];

    cout << "   [0] ";
    pFun();

    pFun = (Fun)pVtab[5][1];

    cout << "   [1] ";
    pFun();

    pFun = (Fun)pVtab[5][2];

    cout << "   [2] ";
    pFun();

    pFun = (Fun)pVtab[5][3];
    
    cout << "   [3] ";
    pFun();
    pFun = (Fun)pVtab[5][4];
    cout << "   [4] 0x" << pFun << endl;
    cout << "[6] B::ib = " << (long)pVtab[6] << endl;
    cout << "[7] B::cb = " << (static_cast<char>((long)pVtab[7])) << endl;
    cout << "[8] B2::ib2 = " << (long)pVtab[8] << endl;
    cout << "[9] B2::cb2 = " << (static_cast<char>((long)pVtab[9])) << endl;
    cout << "[10] D::id = " << (long)pVtab[10] << endl;
    cout << "[11] D::cd = " << (static_cast<char>((long)pVtab[11])) << endl;
}

输出结果

[0] D::B1::_vptr->
   [0] D::f()
   [1] B::Bf()
   [2] D::f1()
   [3] B1::Bf1()
   [4] D::f2()
   [5] 0x1
[1] B::ib = 0
[2] B::cb = B
[3] B1::ib1 = 11
[4] B1::cb1 = 1
[5] D::B2::_vptr->
   [0] D::f()
   [1] B::Bf()
   [2] D::f2()
   [3] B2::Bf2()
   [4] 0x0
[6] B::ib = 0
[7] B::cb = B
[8] B2::ib2 = 12
[9] B2::cb2 = 2
[10] D::id = 100
[11] D::cd = D

GDB调试

x /12x 0x7fffffffcb60
0x7fffffffcb60:	0x0000555555756c58	0x0000000000000123
0x7fffffffcb70:	0x0000555555756c55	0x0000000000000111
0x7fffffffcb80:	0x0000000000000011	0x0000555555756c98
0x7fffffffcb90:	0x0000000000000123	0x0000555555555555
0x7fffffffcba0:	0x0000000000000212	0x0000555555555a22
0x7fffffffcbb0:	0x0000000000000100	0x0000000000000033

虚拟继承

大佬偷懒了,那我们完了啊。

对于这个虚拟继承,和64位机好像有点不一样,我也不知道为啥。
如果有人看懂了回来私信我(留个言也行)。告诉我为啥。

我贴一个自己的实验不保证正确性

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值