搜索

深度探索C++对象模型(9)

gecimao 发表于 2019-06-16 05:51 | 查看: | 回复:

  当编译一个C++程序时,计算机内存被分成了4个区域,一个包括程序的代码,一个包括所有的全局变量,一个是堆栈,还有一个是堆(heap),我们称堆是自由的内存区域,我们可以通过new和delete把对象放在这个区域。你可以在任何地方分配和释放自由存储区。但是要注意因为分配在堆中的对象没有作用域的限制,因此一旦new了它,必须delete它,否则程序将崩溃,这便是内存泄漏。(C#已经通过内存托管解决了这一令人头疼的问题)。C++通过new来分配内存,new的参数是一个表达式,该表达式返回需要分配的内存字节数,这是我以前掌握的关于new的知识,下面看看通过这本书,使我们能够更进一步的了解到些什么。

  很常见的一个代码片段,雷神从来没有考虑过identity如何被构造,或者如何被销毁。因为它肯定在Matrix m1=identity之前就被构造出来了,并且在main函数结束前被销毁了。我们不用考虑这些问题,好象C++就应该这样。但这本书是研究C++底层机制的。既然我们在看这本书,说明我们希望了解C++的编译器又做了那些大量的工作,使得我们可以这样使用对象。

  在C++程序中所有的全局对象都被放在data segment中,如果明确赋值,则对象以该值为初值,否则所配置到内存内容为0。也就是说,如果我们有以下定义

  则v1和v2都被配置于data segment,v1值为1024,v2值为0。(雷神在VC6环境用MFC编程时中发现如果int v2;v2的值不为0,而是-8,不知为什么?编译器造成的?)。

  如果有一个全局对象,并且这个对象有构造函数和析构函数的话,它需要静态的初始化操作和内存释放工作,C++是一种跨平台的编程语言,因此它的编译器需要一种可以移植的静态初始化和内存释放的方法。下面便是它的策略。

  1、为每一个需要静态初始化的档案产生一个_sit()函数,内带构造函数或内联的扩展。

  2、为每一个需要静态的内存释放操作的文件中,产生一个_std()函数,内带析构函数或内联的扩展。

  3、提供一个_main()函数,用来调用所有的_sti()函数,还有一个exit()函数调用所有的_std()函数。

  其中_main()会有一个对identity对象的静态初始化的_sti函数,象下面伪码这样:

  // matrix_c是文件名编码_identity表示静态对象,这样能够保证向执行文件提供唯一的识别符号

  但是被静态初始化的对象有一些缺点,在使用异常时,对象不能被放置在try区段内。还有对象的相依顺序引出的复杂度,因此不建议使用需要静态初始化的全局对象。

  2、第一次处理时,临时对象为false,于是构造函数被调用,然后临时对象被改为true.

  如果一个类定义了构造函数或者析构函数,则当你定义了一个对象数组时,编译器会通过运行库将你的定义进行加工,例如:

  当编译一个C++程序时,计算机的内存被分成了4个区域,一个包括程序的代码,一个包括所有的全局变量,一个是堆栈,还有一个是堆(heap),我们称堆是自由的内存区域,我们可以通过new和delete把对象放在这个区域。你可以在任何地方分配和释放自由存储区。但是要注意因为分配在堆中的对象没有作用域的限制,因此一旦new了它,必须delete它,否则程序将崩溃,这便是内存泄漏。(C#已经通过内存托管解决了这一令人头疼的问题)。C++通过new来分配内存,new的参数是一个表达式,该表达式返回需要分配的内存字节数,这是我以前掌握的关于new的知识,下面看看通过这本书,使我们能够更进一步的了解到些什么。

  一般来说对于new的操作都直截了当,但语言要求每一次对new的调用都必须传回一个唯一的指针,解决这个问题的办法是,传回一个指针指向一个默认为size=1的内存区块,实际上是以标准的C的malloc()来完成。同样delete也是由标准C的free()来完成。原来如此。

  //可能会导致临时对象产生。用来放置a+b的返回值。然后再由 T的copy constructor把临时对象当作c的初值。也有可能直接由拷贝构造将a+b的值放到c中,这时便不需要临时对象。另外还有一种可能通过操作符的重载定义,经named return value优化也可以获得c对象。这三种方法结果一样,区别在于初始化的成本。对临时对象书上有很好的总结:

  在某些环境下,有processor产生的临时对象是有必要的,也是比较方便的,这样的临时对象由编译器决定。

  因为临时对象是根据执行期语义有条件的产生,因此它的生命规则就显得很复杂。C++标准要求凡含有表达式执行结果的临时对象,应该保留到对象的初始化操作完成为止。当然这样也会有例外,当一个临时对象被一个引用绑定时,对象将残留,直到被初始化的引用的生命结束,或者超出临时对象的作用域。

  好了今天很有收获,马上就会结束这本书的学习了。下一章的标题 站在对象模型的尖端 我有些迫不及待了。

  * 网友发言均非本站立场,本站不在评论栏推荐任何网店、经销商,谨防上当受骗!

  更多

  大公司晨读:华为5G商用图标曝光;小米停止MIUI全球Beta测试计划

  还在浪费手机的电源键寿命?OPPO K3让查看未接来电未读信息更方便!

  专业摄影领域集结号 索尼SEL200600G及SEL600F40GM试用体验

本文链接:http://robynlynne.com/duixiangmoxing/557.html
随机为您推荐歌词

联系我们 | 关于我们 | 网友投稿 | 版权声明 | 广告服务 | 站点统计 | 网站地图

版权声明:本站资源均来自互联网,如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

Copyright @ 2012-2013 织梦猫 版权所有  Powered by Dedecms 5.7
渝ICP备10013703号  

回顶部