从一道面试题看深拷贝、浅拷贝构造函数问题.docVIP

从一道面试题看深拷贝、浅拷贝构造函数问题.doc

  1. 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
  2. 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载
  3. 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
  4. 4、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
  5. 5、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们
  6. 6、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
  7. 7、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
Trend科技的一道面试题: 请看下面的程序,说说会出现什么问题? #include iostream #include cstdlib #include vector using?? namespace?? std; class?? CDemo?? { public: ??? CDemo():str(NULL){}; ??? ~CDemo() ??? { ??????? if(str)?? delete[]?? str; ??? }; ??? char*?? str; }; int?? main(int?? argc,?? char**?? argv)?? { ??? CDemo?? d1; ??? d1.str=new?? char[32]; ??? strcpy(d1.str, trend?? micro); ??? vectorCDemo?? *a1=new?? vectorCDemo(); ?? ??? a1-push_back(d1); ??? delete?? a1; ?? ??? return EXIT_SUCCESS; } 这个程序在退出时,会出问题,什么问题?重复delete同一片内存,程序崩溃。 我们把析构函数改为如下,可以更清楚的看到这一点: ??? ~CDemo() ??? { ??????? if(str) ??????? { ??????????? static int i=0; ??????????? coutCDemoi++=(int*)this,??? str=(int *)strendl; ??????????? delete[]?? str;???? ??????? } ??? }; ?? 运行时我们发现打印如下信息: CDemo0=000309D8,?????? str=000307A8 CDemo1=0013FF70,?????? str=000307A8 也就是说,发生了CDemo类的两次析构,两次析构str所指向的同一内存地址空间(两次str值相同=000307A8)。 为什么? 《程序员面试宝典》第二版,P99,有句解释“vector对象指针能够自动析构,所以不需要调用delete a1,否则会造成两次析构对象” 我切以为这句话说的有点不妥。任何对象如果是通过new操作符申请了空间,必须显示的调用delete来销毁这个对象。所以“delete?? a1; ”这条语句是没有错误的。 这句话“vectorCDemo?? *a1=new?? vectorCDemo(); ”定一个指针,指向 vectorCDemo,病用new操作符进行了初始化, 我们必须在适当的时候释放a1所占的内存空间,所以“delete?? a1; ”这句话是没有错误的。另外,我们必须明白一点,释放vector对象,vector所包含的元素也同时被释放。 那到底那里错误? 这句a1的声明和初始化语句“vectorCDemo?? *a1=new?? vectorCDemo(); ”说明a1所含元素是“CDemo”类型的,在执行“a1-push_back(d1); ”这条语句时,会调用CDemo的拷贝构造函数,虽然CDemo类中没有定义拷贝构造函数,但是编译器会为CDemo类构建一个默认的拷贝构造函数(浅拷贝),这就好像任何对象如果没有定义构造函数,编译器会构建一个默认的构造函数一样。 正是这里出了问题。a1中的所有CDemo元素的str成员变量没有初始化,只有一个四字节(32位机)指针空间。 “a1-push_back(d1);”这句话执行完后,a1里的CDemo元素与d1是不同的对象,但是a1里的CDemo元素的str与d1.str指向的是同一块内存,这从后来的打印信息就可以看出来。 我们知道,局部变量,如“CDemo?? d1; ” 在main函数退出时,自动释放所占内存空间, 那么会自动调用CDemo的析构函数“~CDeme”,问题就出在这里。 前面的“delete?? a1;”已经把 d1.str 释放了(因为a1里的CDemo元素的str与d1.str指向的是同一块内存),main函数退出时,又要释放已经释放掉的 d1.str 内存空间,所以程序最后崩溃。 解释清楚了。 这里最核心的问题归根结底就是浅拷贝和深拷贝的问题。如果CDemo类添加一个这样的拷贝构造函数就可以解决问题: ??? CDemo(const?? CDemo?? cd) ??? { ??????? this-str?? =?? new?? char[strlen(cd.str)+1]; ??????? strcpy(str,cd.str); ???

文档评论(0)

xcs88858 + 关注
实名认证
文档贡献者

该用户很懒,什么也没介绍

版权声明书
用户编号:8130065136000003

1亿VIP精品文档

相关文档