c++对象的放置

原创 2001年11月02日 19:04:00

  (声明:本文参考了《深度探索c++对象模型》这本书,我连例子都和此书一样,如有人认为是偷的话,还请各位原谅,^_^)
   经历过从c到c++的人,一定想知道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++类究竟是如何放置的(我不认为我是在转牛角尖).

  
 

C++ new的放置语法

#include using namespace std;struct Node{    int u;    Node(int uu = 0):u(uu){        //cout ...
  • intheway_acm
  • intheway_acm
  • 2010年06月04日 23:09
  • 926

New的放置语法

本文章转自wangyi//placenew2.cpp---new,placement new,no delete #include #include #include//放置语法中需调用 using ...
  • xl19900502
  • xl19900502
  • 2014年04月13日 01:01
  • 509

Delphi中对象释放的问题

写前台程序的时候经常遇到自己创建对象的情况,我们知道delphi没有类似Java的内存回收技术, 所以要手动释放自己创建的对象。   大部分对象创建的时候,在create构造函数中都有一个AOwn...
  • Renruyi666
  • Renruyi666
  • 2016年10月01日 15:14
  • 302

js拖拽和放置(javascript drag and drop)

 Submitted by koyoz on 2008, June 8, 10:49 PM. javascriptjs拖拽和放置效果.这个drag-drop.htmlXML/HTML代码>   htm...
  • a9529lty
  • a9529lty
  • 2008年07月25日 09:50
  • 9113

Java中对象的放置安排与C++中对象的放置安排

Java中,所有的对象都存放在堆(Heap,一种通用的内存池)中;而对象的引用是存放在堆栈(Stack)中的。我们可以通过String直接声明的字符串与new String声明出来的字符串使用equa...
  • u012712087
  • u012712087
  • 2015年06月06日 20:22
  • 407

(31)放置Actor

Actor 是可以放置在关卡中的任意对象。Actor 是支持三维变换的通用类,比如如平移,旋转和缩放变换。 Actor 可以通过游戏代码(C++或蓝图)来创建(Spawn)及销毁。在 C++ 中,AA...
  • zl908760230
  • zl908760230
  • 2017年05月16日 09:30
  • 97

C++中的对象指针和对象引用

在C++中,可以说明指向类的数据成员和成员函数的指针。    指向数据成员的指针格式如下:    ::*    指向成员函数的指针格式如下:    (::*)()    例如,设有如下一个类A: ...
  • guoyuqi0554
  • guoyuqi0554
  • 2011年04月23日 14:43
  • 7462

深入理解C++中的对象和对象引用

先来看一个入门级的程序:
  • stpeace
  • stpeace
  • 2014年11月07日 00:04
  • 6925

C++对象模型之简述C++对象的内存布局

在C++中,有两种类的成员变量:static和非static,有三种成员函数:static、非static和virtual。那么,它们如何影响C++的对象在内存中的分布呢? 当存在继承的情况下,其内存...
  • ljianhui
  • ljianhui
  • 2015年05月22日 02:28
  • 10039

noip2009初赛-国王放置

2009C-4-2(国王放置)在n*m的棋盘上放置k个国王,要求k个国王互相不攻击,有多少种不同的放置方法。假设国王放置在第(x,y)格,国王的攻击的区域是:(x-1,y-1),(x-1,y),(x-...
  • sjtu081200
  • sjtu081200
  • 2015年08月23日 17:21
  • 971
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:c++对象的放置
举报原因:
原因补充:

(最多只允许输入30个字)