< meta http-equiv="description" content=" 其实这里的标题或许有点大了,简单的说,类的非static成员是按照声明的顺序存放在内存区的,而类的static成员和一般的static变量的存储格式一样.我不从简单的东西入手了,直接从一个相对复杂的多重继承的例子入手."/>

c++类究竟是如何放置的

[来源] 达内    [编辑] 达内   [时间]2012-06-19

其实这里的标题或许有点大了,简单的说,类的非static成员是按照声明的顺序存放在内存区的,而类的static成员和一般的static变量的存储格式一样.我不从简单的东西入手了,直接从一个相对复杂的多重继承的例子入手.

 +的人,一定想知道c++编译器是如何安排类的成员的.这里我大概的作一下介绍,并有一些代码供你进行测试,希望对大家有点作用吧.

      其实这里的标题或许有点大了,简单的说,类的非static成员是按照声明的顺序存放在内存区的,而类的static成员和一般的static变量的存储 格式一样.我不从简单的东西入手了,直接从一个相对复杂的多重继承的例子入手.看下面的代码:
    class Point2d
    {
    public:
        int _x,_y;
        virtual f(){}//保证Point2d有个虚拟指针
    };
    class Point3d:public Point2d
    {
    public:
        int _z;
    };
    class Vertex
    {
    public:
       virtual void h(){}//保证Vertex3d的第二基础类有个vptr
        int next;
    };
    class Vertex3d:public Point3d,public Vertex
    {
    public:
        int mumble;
    };
    Point2d,Point3d,Vertex,Vertex3d的继承关系能看得出来吧.再看主函数
    int main()
    {
        Vertex3d v3d;
        Vertex*pv;
        pv=&v3d;
        int*x=&v3d._x;//获取v3d的成员的地址
        int*y=&v3d._y;
        int*z=&v3d._z;
        int*n=&v3d.next;
        int*mem=&v3d.mumble;
        cout<<"*v3d= "<<&v3d<<endl;//输出第一个vptr
        cout<<"*x=   "<<x<<endl;//输出成员的x的地址
        cout<<"*y=   "<<y<<endl;//….
        cout<<"*z=   "<<z<<endl;//…..
        cout<<"*pv=  "<<pv<<endl;/.输出第二个vptr
        cout<<"*n=   "<<n<<endl;//…….
        cout<<"*mem= "<<mem<<endl;//……..
        return 0;
    }
    我在vc6.0编译运行的结果是:
    &v3d = 0x0012ff64
    x    = 0x0012ff68
    y    = 0x0012ff6c
    z    = 0x0012ff70
    pv   = 0x0012ff74
    n    = 0x0012ff78
    mem = 0x0012ff7c
    从上面的输出结果来看,对象是如何布局的就一幕了然了,如果你不信,可以自己可以试试看,输出Vertex3d的尺寸瞧一瞧,^_^.注意,Vertex3d内有两个vptr,如果还 不知道为什么会有的话,建议你先去看看书吧!!

      补充:我想到另一个比较直观的方法,就是利用Placement Operator New(PON)的方法,相对应的还有Placement Operator Delete.至于这些概念,我就不多说了,^_^.刚才看到那些地址都是内存中的,但可以利用(PON)把那些地址放倒一个数组中去,那样会更直观,不 信,你看着:
    #include<iostream.h>
    #include<new.h>
    class Point2d
    {
    public:
        int _x,_y;//
        Point2d(){
            _x=10;
            _y=20;
    }
        virtual f(){}
    };
    class Point3d:public Point2d
    {
    public:
        int _z;
        Point3d(){_z=30;}
    };
    class Vertex
    {
    public:
        int next;
        Vertex(){next=40;}
        virtual void f(){}
        virtual void g(){}
        virtual void h(){}
    };
    class Vertex3d:public Point3d,public Vertex
    {
    public:
        int mumble;
        Vertex3d(){mumble=50;}
    };
    int main()
    {
        long str[30];
        Vertex3d*array=new(str)Vertex3d;
       for(int i=0;i<sizeof(Vertex3d)/4;i++)
       {
          cout<<str[i]<<endl;
       }
       //这里需要显示调用Vertex3d的析构函数,
       return 0;

    }

 

    让我慢慢说来,这里的一些类,只是添加了构造函数而已,为的是能够直观.我定义了一个数组为的放置Vertex3d对象,类型为long是由于上面的类的每个成员都是四个字节,而虚拟指针(vptr)也是四个字节,这样输出很方便.

 

    Vertex3d*array=new(str)Vertex3d;这条语句就是用了PON方法,在数组str中放置一个Vertex3d对象,一切都已 经做好了,对象的布局就是在数组str中,不妨去看看str中的内容,这里我就不打算把输出结果写出来了,自己调试.有个缺陷就是看不到virtual函 数的函数地址(虽然有其他的方法,但不直观.vc调试模式下直接就可以看,或许我会想到办法的)

 

        就简单说这么些了,vc编译器的debug模式下可以直接看到的,更直观,但我的目的只是弄懂

c++

类究竟是如何放置

资源下载