《c++程序性能优化》——C++对象模型

第二章 C++对象模型

 ~内存区~

一般分为以下五个部分

1全局/静态变量区

2常量数据区

3代码区

4栈

5堆

 

全局变量和静态变量,以及局部的静态变量储存在全局/静态变量区。

字符串存储在常量数据区,而且是4个字节对齐的。

程序中的其他字符串常量,如printf()中函数中的格式串,也是存储在常量数据区中。

通过new和malloc或得的内存是在堆中的内存。堆上分配内存是以16字节对齐的。

 

~全局/静态变量区和常量数据区~

 

全局/静态变量区和常量数据区是程序编译阶段已经分配好的,在整个程序运行的过程中是始终存在的,用于存储全局变量,静态变量,和字符串变量,其中字符串变量去是不可修改的,

 

如果在同一个类中多个对象共享数据,可以使用全局变量,但是会破坏类的封装性。c++提供了类的静态成员变量,可以在多个对象中共享数据。类的静态成员变量存储在全局/静态变量区,只有一份拷贝,由内的对象共享。

 

~堆和栈~

栈用来存储自由变量和传递参数,堆存储的事通过new创建对象和malloc申请内存

栈没有碎片,会自动释放,而堆不会自动释放,malloc()用free()释放,new用delete释放

这两个区别还有

1大小,一个程序的栈的大小事编译器固定的,比如vs2003规定是1Mb。而堆得大小受限于虚拟内存的大小,可以用来分配创建较大的数据对象。

2效率,栈上的内存是系统自动分配的,效率比较高,不会产生碎片。而堆上的内存赢开发人员确定,系统要通过一定的算法来寻找合适大小的空闲区,返回给程序,效率低。

 

c++中的对象

~对象的生命周期~

1通过定义变量创建对象

变量的作用域决定的对象的生命周期

注意:全局变量的作用域是这个程序,被声明为全局变量的对象在main()函数前创建,在退出main()时销毁。声明为静态变量的对象在第一次进入作用域创建,程序推出是销毁。

2通过new创建对象,只要没有调用delete该对象就一直存在,容易造成内存泄露

3通过实现创建对象。这些临时的对象一般是拷贝构造函数创建的。当函数的参数和返回值时值传递对象时需要把实参复制一份。构造一个副本,创建一个临时对象。在函数退出时销毁。

这个问题可以用引用和指针的方法解决。

 

 

~对象的内存布局~

 

      一个c++类包括成员数据和成员函数,成员数据包括静态成员数据和非静态成员数据;成员函数可以分为静态成员函数,非静态成员函数和虚函数。

      静态成员数据在全局/静态变量区存储,不作为对象占据内存的一部分。

      c++编译器在遇到有虚函数的类时,就会分配一个指针指向函数地址表,叫做虚函数表占4个字节。而且占据的事一个对象以开始的4个字节。  

      有以下4个结论

      1非静态数据成员是影响对象占据内存大小的主要因素,随着对象的数目的增加,非静态数据成员占据的内存会相应增加。

      2所有的兑现共享一份静态数据成员,所以静态数据成员占据的内存数量不会随着对象的数目增加而增加。

      3静态成员函数和非静态成员函数不会影响对象的内存大小,虽然其实现会占据相应的内存空间,相当于c中的结构体,在函数区通过this来查找对应的函数,也不会随着对象的增加而增加。

      4如果对象中包含虚函数,会增加4个字节的空间,不论有多少个虚函数。

 

      关于VC++虚继承下内存布局的结论:
1 首先排列非虚继承的基类实例;
2 有虚基类时,为每个基类增加一个隐藏的vbptr,除非已经从非虚继承的类那里继承了一个vbptr;
3 排列派生类的新数据成员;
4 在实例最后,排列每个虚基类的一个实例。

 

 

 

    

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值