Fork me on GitHub

[转]C++对象内存分配

很久以前收藏的原文地址找不到了。

单继承对象内存分配:

#include <iostream>
using namespace std;
class Base1
{
public:
    long ibase1;
    int ibase12;
    Base1():ibase1(10),ibase12(100) {}
    virtual void f()
    {
        cout << "Base1::f()" << endl;
    }
    virtual void g()
    {
        cout << "Base1::g()" << endl;
    }
    virtual void h()
    {
        cout << "Base1::h()" << endl;
    }

};
class Base2
{
public:
    int ibase2;
    long ibasee21;
    Base2():ibase2(20),ibasee21(21) {}
    virtual void f()
    {
        cout << "Base2::f()" << endl;
    }
    virtual void g()
    {
        cout << "Base2::g()" << endl;
    }
    virtual void h()
    {
        cout << "Base2::h()" << endl;
    }
};


class Base3
{
public:
    int ibase3;
    Base3():ibase3(30) {}
    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:
    int iderive;
    Derive():iderive(100) {}
    virtual void f()
    {
        cout << "Derive::f()" << endl;
    }
    virtual void g1()
    {
        cout << "Derive::g1()" << endl;
    }
};
typedef void(*Fun)(void);
Fun pFun;
int main()
{
    Derive d;
    int** pVtab = (int**)&d;
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; cout << "[2] Base1.ibase12 = " << (long)pVtab[2]<< endl; int s = sizeof(Base1)/4; cout << "[" << s << "] Base2::_vptr->"<<endl; pFun = (Fun)((int**)(&d))[s][0]; cout << " [0] "; pFun(); pFun = (Fun)*(int *)(*(pVtab+s)+1); cout << " [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 = " << (int)*(pVtab+s+1) << endl;//成员变量存放的也只是指针? cout << "["<< s+2 <<"] Base2.ibase21 = " << (int)pVtab[s+2] << endl; s = s + sizeof(Base2)/4; 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 = " << (int)pVtab[s] << endl; s++; cout << "["<< s <<"] Derive.iderive = " << (int)pVtab[s] << endl; }

重复继承内存分配:

 

#include <iostream>
using namespace std;

class B
{

    public:
        int 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:
        int 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:
        int 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:
        int 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** pVtab = NULL;
    Fun pFun = NULL;

int main()
{
     D d;
    pVtab = (int**)&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 = " << (int)pVtab[1] << endl;
    cout << "[2] B::cb = " << (char)pVtab[2] << endl;
    cout << "[3] B1::ib1 = " << (int)pVtab[3] << endl;
    cout << "[4] B1::cb1 = " << (char)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 = " << (int)pVtab[6] << endl; cout << "[7] B::cb = " << (char)pVtab[7] << endl; cout << "[8] B2::ib2 = " << (int)pVtab[8] << endl; cout << "[9] B2::cb2 = " << (char)pVtab[9] << endl; cout << "[10] D::id = " << (int)pVtab[10] << endl; cout << "[11] D::cd = " << (char)pVtab[11] << endl; }

我们可以看见,最顶端的父类B其成员变量存在于B1和B2中,并被D给继承下去了。而在D中,其有B1和B2的实例,于是B的成员在D的实例中存在两份,一份是B1继承而来的,另一份是B2继承而来的。所以,如果我们使用以下语句,则会产生二义性编译错误:

 

D d;

d.ib = 0;               //二义性错误

d.B1::ib = 1;           //正确

d.B2::ib = 2;           //正确

 

注意,上面例程中的最后两条语句存取的是两个变量。虽然我们消除了二义性的编译错误,但B类在D中还是有两个实例,这种继承造成了数据的重复,我们叫这种继承为重复继承。重复的基类数据成员可能并不是我们想要的。所以,C++引入了虚基类的概念。

 钻石型多重虚拟继承内存分配:

#include <iostream>
using namespace std;

class B
{

public:
    int 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 : virtual public B//虚拟继承
{

public:
    int 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:  virtual public B//虚拟继承
{
public:
    int 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:
    int 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** pVtab = NULL;
Fun pFun = NULL;

int main()
{
    D dd;

pVtab
= (int**)&dd; cout << "[0] D::B1::_vptr->" << endl; pFun = (Fun)pVtab[0][0]; cout << " [0] "; pFun(); //D::f1(); pFun = (Fun)pVtab[0][1]; cout << " [1] "; pFun(); //B1::Bf1(); pFun = (Fun)pVtab[0][2]; cout << " [2] "; pFun(); //D::Df(); pFun = (Fun)pVtab[0][3]; cout << " [3] "; cout << pFun << endl; //cout << pVtab[4][2] << endl; cout << "[1] = 0x"; cout << (int*)((&dd)+1) <<endl; //???? cout << "[2] B1::ib1 = "; cout << *((int*)(&dd)+2) <<endl; //B1::ib1 cout << "[3] B1::cb1 = "; cout << (char)*((int*)(&dd)+3) << endl; //B1::cb1 //--------------------- cout << "[4] D::B2::_vptr->" << endl; pFun = (Fun)pVtab[4][0]; cout << " [0] "; pFun(); //D::f2(); pFun = (Fun)pVtab[4][1]; cout << " [1] "; pFun(); //B2::Bf2(); pFun = (Fun)pVtab[4][2]; cout << " [2] "; cout << pFun << endl; cout << "[5] = 0x"; cout << *((int*)(&dd)+5) << endl; // ??? cout << "[6] B2::ib2 = "; cout << (int)*((int*)(&dd)+6) <<endl; //B2::ib2 cout << "[7] B2::cb2 = "; cout << (char)*((int*)(&dd)+7) << endl; //B2::cb2 cout << "[8] D::id = "; cout << *((int*)(&dd)+8) << endl; //D::id cout << "[9] D::cd = "; cout << (char)*((int*)(&dd)+9) << endl;//D::cd cout << "[10] = 0x"; cout << (int*)*((int*)(&dd)+10) << endl; //--------------------- cout << "[11] D::B::_vptr->" << endl; pFun = (Fun)pVtab[11][0]; cout << " [0] "; pFun(); //D::f(); pFun = (Fun)pVtab[11][1]; cout << " [1] "; pFun(); //B::Bf(); pFun = (Fun)pVtab[11][2]; cout << " [2] "; cout << pFun << endl; cout << "[12] B::ib = "; cout << *((int*)(&dd)+12) << endl; //B::ib cout << "[13] B::cb = "; cout << (char)*((int*)(&dd)+13) <<endl;//B::cb }

 

posted @ 2012-09-25 20:57  zhanjindong  阅读(381)  评论(0编辑  收藏  举报
TOP