- 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
- 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
- 4、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
- 5、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们。
- 6、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
- 7、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
第五章 堆与拷贝构造函数
* 实验 任务:员工考评问题 * 实验 注意事项 提示: 注意定义拷贝构造函数,避免浅拷贝 * 堆与拷贝构造函数 全局变量、静态数据、常量存放在全局数据区,所有类成员函数和非成员函数代码存放在代码区,为运行函数而分配的局部变量、函数参数、返回数据、返回地址等存放在栈区,余下的空间都被作为堆区。 操作堆内存时,如果分配了内存,就有责任回收它,否则运行的程序将会造成内存泄漏。这与函数中在栈区分配局部变量有本质的不同 * 函数“void* malloc(size-t);”和“void free(void*);”在头文件malloc.h中声明 操作符new和delete是C++语言的一部分,无须包含头文件 。 对C++来说, 管理堆区是一件十分复杂的工作,频繁地分配和释放不同大小的堆空间,将会产生堆内碎块。 从C++的立场上看,不能用malloc()函数的一个原因是,它在分配空间的时候不能调用构造函数。类对象的建立是分配空间、构造结构以及初始化的三位一体,它们统一由构造函数来完成。 * 不必显式指出从new返回的指针类型,因为new知道要分配对象的类型是Tdate。 而且new还必须知道对象的类型,因为它要藉此调用构造函数。 如果是分配局部对象,则在该局部对象退出作用域时(要么程序执行遇到函数结束标记“}”,要么遇到返回语句)自动调用析构函数。但是堆对象的作用域是整个程序生命期,所以除非程序运行完毕,否则堆对象作用域不会到期。堆对象析构是在释放堆对象语句delete执行之时。上面的堆对象在执行delete pS;语句时,C++自动调用其析构函数。 * “pD=newTdate(1,1,1998);”这一句,使new去调用了构造函数Tdate(int,int,int),new是根据参数匹配的原则来调用构造函数的。如果上一句写成: pD=new Tdate; 则由于Tdate类没有默认构造函数(已被Tdate(int,int,int)覆盖)而使该语句报错。 从堆中还可以分配对象数组。 例如,下面的代码分配了参数给定的对象个数,并在函数结束时,予以返还: * 分配过程将激发noOfObjects次构造函数的调用,从0~noOfObjects-1。调用构造函数的顺序依次为pS[0],pS[1],pS[2],…pS[noOfObjects-1]。 由于分配数组时,new的格式是类型后面跟[元素个数],不能再跟构造函数参数,所以,从堆上分配对象数组,只能调用默认的构造函数,不能调用其他任何构造函数。 如果该类没有默认构造函数,则不能分配对象数组。 delete[ ] pS中的[ ]是要告诉C++,该指针指向的是一个数组。如果在[ ]中填上了数组的长度信息,C++编译系统将忽略,并把它作为[ ]对待。但如果忘了写[ ],则程序将会产生运行错误。 * 拷贝构造函数和默认拷贝函数 可用一个对象去构造另一个对象,或者说,用另一个对象值初始化一个新构造的对象,例如: Student S1(Jenny);Student s2=sl; //用s1的值去初始化s2 对象作为函数参数传递时,也要涉及对象的拷贝,例如: 函数fn()的参数传递的方式是传值, 参数类型是Student,调用时,实参ms传给了形参fs,ms在传递的过程中是不会改变的,形参fs是ms的一个拷贝。这一切是在调用的开始完成的,也就是说,形参fs用ms的值进行构造。 这时候,调用构造函数Student(char*)就不合适,新的构造函数的参数应是Student,也就是:Student(Student S); * 因为对象的类型多种多样,不像基本数据类型这么简单,有些对象还申请了系统资源,如下图所示,s对象拥有了一个资源,用s的值创建一个t对象,如果仅仅只是二进制内存空间上的s拷贝,那意味着t也拥有这个资源了。由于资源归属权不清,将引起资源管理的混乱。 * 类定义中,如果未提供自己的拷贝构造函数, 则C++提供一个默认拷贝构造函数,就像没有提供构造函数时,C++提供默认构造函数一样。 C++提供的默认拷贝构造函数工作的方法是, 完成一个成员一个成员的拷贝。如果成员是类对象,则调用其拷贝构造函数或者默认拷贝构造函数。 * 在默认拷贝构造函数中,拷贝的策略是逐个成员依次拷贝。 但是,一个类可能会拥有资源,当其构造函数分配了一个资源(例如堆内存)的时候,会发生什么呢? 如果拷贝构造函数简单地制作了一个该资源的拷贝,而不对它本身分配,就得面临一个麻烦的局面:两个对象都拥有同一个资源。当对象析构时,该资源将经历两次资源返还 * 当一个对象创建时,分配了资源,这时,就需要定义自己的拷贝构造函数,使之不但拷贝成员,也拷贝资源。 * 当一个对象
文档评论(0)