C++中对象的内存映像

上传人:仙*** 文档编号:244140244 上传时间:2024-10-02 格式:PPT 页数:20 大小:2.40MB
返回 下载 相关 举报
C++中对象的内存映像_第1页
第1页 / 共20页
C++中对象的内存映像_第2页
第2页 / 共20页
C++中对象的内存映像_第3页
第3页 / 共20页
点击查看更多>>
资源描述
单击此处编辑母版标题样式,单击此处编辑母版文本样式,第二级,第三级,第四级,第五级,*,*,C+,中对象的内存映像,1,内容,数据成员变量在内存中的布局,类在内存中的映像,多态的实现机制,集体讨论,2,typedef,unsigned char,BYTE,;,enum,Color,Red=0X01,Blue,Green,Yellow,Black,;,struct,car,bool,m_hasSkyLight,;,Color,m_color,;,bool,m_isAutoShift,;,double,m_price,;,BYTE,m_seatNum,;,;,类型,字节数,char,1,bool,1,int,4,float,4,double,8,该结构体的对象在内存中占多少个字节?,32,位平台下,15,?,3,32,4,自然对齐,基本数据类型(,short,int,double,)的变量不能简单的存储于内存中的任意地址处,它们的起始地址必须能被它们占用的字节数整除。,复合类型是由基本类型构成的,对象的起始地址要能够满足要求最严格的成员变量自然对齐的要求,如果类中有复合类型的成员变量,依次往后类推。除了整个对象要求自然对齐外,内部的成员变量也要自然对齐;编译器不仅考虑了单个对象的自然对齐要求,还考虑到了对象数组的对齐要求。,5,m_price,m_color,?(,填充,),m_hasSkyLight,m_isAutoShift,?(,填充,),m_seatNum,?(,填充,),0 x00031D10:,0 x00031D14:,0 x00031D18:,0 x00031D20:,0 x00031D28:,4,字节,4,字节,8,字节,8,字节,8,字节,Car,的内存布局,Typedef,unsigned char,BYTE,;,Enum,Color,Red=0X01,Blue,Green,Yellow,Black,;,Struct,car,bool,m_hasSkyLight,;,Color,m_color,;,bool,m_isAutoShift,;,double,m_price,;,BYTE,m_seatNum,;,;,204048:,末尾填充?,编译器按照成员变量声明的顺序分配空间。,为满足各个成员变量自然对齐的要求,可能会在末尾填充若干字节。,对象本身的自然对齐取决于自然对齐要求最高的那个成员变量。,6,如上,编译器不会随便地在任意一个内存地址上创建一个,C+/C,的变量和对象,它们在内存中的首地址要满足一定的条件,数据成员也不是紧挨在一起的,而且每个成员的地址也不是随意安排的,都是经过了编译器的精心规划和计算,这样才能提高对象及其成员的访问效率。,解决的办法,按照成员变量所占字节从大到小的顺序依次声明。,如果满足所有成员的自然对齐,内存将会有大量的浪费,如何有效的利用内存呢?,7,Typedef,unsigned char,BYTE,;,enum,Color,Red=0X01,Blue,Green,Yellow,Black,;,Struct,car,double,m_price,;,Color,m_color,;,bool,m_hasSkyLight,;,bool,m_isAutoShift,;,BYTE,m_seatNum,;,;,m_price,m_color,m_hasSkyLight,m_isAutoShift,m_seatNum,?,填充,0 x00031010:,0 x00031018:,0 x0003101C:,0 x0003101D:,0 x0003101E:,0 x0003101C:,4,字节,4,字节,8,字节,调整后的内存布局,调整后,对象所占内存变为,16,个字节,末尾只有一个填充字节。,如果想将末尾填充的字节也利用了,可以吸收掉末尾的填充字节,在该例中,可以将,m_seatNum,设置为,short,型。,综上所述,类的数据成员类型的选择,声明顺序即排列,采用的对齐方式,都将影响着对象的实际大小和访问效率。,8,在,MS C+/C,中,支持用户在代码中显示的指定复合类型的对齐方式,可用的对齐方式有,1,,,2,,,4,,,8,,,16.,复合类型对象在内存中创建后,每个成员本身的地址取决于它们相对于对象起始地址的偏移字节数,而这个偏移字节数不仅仅与排在它们前面的成员的大小有关,还与用户为这个对象类型指定的成员对齐方式有关。,#,ifdef,_MSC_VER,#,prama,pack(push,4)/,按,4,字节对齐,#,endif,typedef,unsigned char,BYTE,;,enum,Color,Red=0X01,Blue,Green,Yellow,Black,;,Struct,car,bool,m_hasSkyLight,;,Color,m_color,;,bool,m_isAutoShift,;,double,m_price,;,BYTE,m_seatNum,;,;,#,ifdef,_MSC_VER,#,pragma,pack(pop,),#,endif,m_price,m_color,m_hasSkyLight,m_isAutoShift,m_seatNum,0 x00031D10:,0 x00031D18:,0 x00031D1C:,0 x00031D24:,0 x00031D14:,4,字节,4,字节,8,字节,?,填充,?,填充,?,填充,4,字节,4,字节,4,字节对齐映像,9,声明顺序和对齐方式一经确定,每个成员的地址偏移量就确定了,不随对象的改变而改变。一个复合类型的对象在内存中满足了自然对齐的要求,但是其中一些数据成员本身却可能不是自然对齐的。上例中,按,4,个字节自然对齐时,其大小变为,24,个字节,而成员,m_price,的地址却不能被,8,整除。,内容,数据成员变量在内存中的布局,类在内存中的映像,多态的实现机制,集体讨论,10,11,Class Rectangle,public:,Rectangle():m_length(0),m_width(0),Rectangle().,float,GetLength,()const return,m_length,;,float,GetWidth,()const return,m_width,;,void Draw(),protected:,Rectangle(const Rectangle©).,Rectangle&operator=(const Rectangle&assign).,private:,float,m_length,;,float,m_width,;,static unsigned,int,m_count,;,;,12,用户内存区,m_length,m_width,Rectangle,rect,1;,m_length,m_width,Rectangle,rect,1;,.,.,.,程序静态数据区,m_count,代码段,Rectangle:Rectangle,(const Rectangle©),Rectangle:operator=(const Rectangle&assign),Rectangle:Rectangle,(),Rectangle:Rectangle,(),Rectangle:Getlength,(),Rectangle:Getwidth,(),Rectangle,对象的内存映像,Rectangle:Draw,(),内容,数据成员变量在内存中的布局,类在内存中的映像,多态的实现机制,集体讨论,13,14,class Shape,public:,Shape():m_color,(0),virtual shape(),float,GetColor,const return,m_color,;,void,SetColor,(float,color)m_color,=color;),virtual Draw()=0;/,纯虚函数,private:,float,m_color,;,;,class Rectangle:public Shape,public:,.,private:,.,15,程序静态数据区,m_count,代码段,Rectangle:Rectangle,(const Rectangle©),Rectangle:operator=(const Rectangle&assign),Rectangle:Rectangle,(),Rectangle:Rectangle,(),Rectangle:Getlength,(),Rectangle:Getwidth,(),Rectangle:Draw,(),用户内存区,Rectangle,rect,1;,Rectangle,rect,2;,.,.,.,m_length,m_width,m_color,_,vptr,m_length,m_width,m_color,_,vptr,type_info,type_info_ptr,destructor_ptr,draw_ptr,加上继承和多态特性的,Rectangle,对象模型,Shape:GetColor,(),Shape:SetColor,(),16,增加了继承和虚函数的类的对象模型更加复杂,具体规则如下:,为每一个多态类创建一个虚函数指针数组,vtable,,该类的所有虚函数(继承自基类的或者新增的)的地址都保存在这张表里。,多态类的每一个对象中安插一个指针成员,vptr,(,隐藏的,),,其类型为指向函数指针的指针,它总是指向所属的,vtable,也就是说,,vptr,当前所在的对象是什么类型,就指向这个类型的,vtable,.,如果基类已经插入了,vptr,,则派生类将继承和重用该,vptr,.,为了支持,RTTI,(,Runtime Type Identification,),为每一个多态类创建一个,type_info,对象,并把其地址保存在,vtable,一个固定位置,一般为第一个位置,这取决于编译器。,只有虚函数访问需要经过,vptr,的间接寻址,增加了一层间接性,带来了一些额外的开销。,17,关于,vtable,中虚函数指针的排列顺序,有以下规则:,一个虚函数如果在当前,class,中第一次出现(如果在基类中已经出现过,不算第一次),则将其地址插入到该,class,的每一个,vtable,的尾部。,如果派生类改写了基类的虚函数,则这个函数的地址在派生类,vtable,中的位置与它在基类,vtable,中的位置一致;也就是说虚函数第一次出现的时,它在,vtable,中的位置一旦确定,就不会随着派生层次的增加而改变。,派生类没有改写的基类的虚函数被继承插入到派生类,vtable,中,且在派生类,vtable,中的位置与其在基类中的位置相同,即派生类的,vtable,布局兼容其基类的,vtable,。,18,class Shape,public:,Shape():m_color,(0),virtual shape(),float,GetColor,const return,m_color,;,void,SetColor,(float,color)m_color,=color;),virtual Draw()=0;/,纯虚函数,private:,float,m_color,;,;,class Rectangle:public Shape,public:,.,virtual,int,GetName,();,Private:,.,19,type_info_ptr,destructor_ptr,draw_ptr,Shape:_vtable,type_info,of Shape,Shape:Shape,(),0,getName_ptr,Rectangle:_vtable,type_info_ptr,destructor_ptr,draw_ptr,ty
展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 管理文书 > 施工组织


copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!