- 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
- 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
- 4、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
- 5、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们。
- 6、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
- 7、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
C++箴言:使用相同形式的new和delete
...
delete stringArray;
每件事看起来都很正常。也为 new 搭配了一个 delete。但是,仍旧
有某件事情彻底错了。程序的行为是未定义的。直到最终,stringArray 指
向的 100 个 string 对象中的 99 个不太可能被完全销毁,由于它们的
析构函数或许根本没有被调用。
当你使用了一个 new 表达式 (也就是说,通过使用 new 动态创立一
个对象),有两件事情会发生。首先,安排内存(通过一个被称为 operator
new 的函数——参见 Item 49 和 51)。其次,一个或多个构造函数在这
些内存上被调用。当你使用一个 delete 表达式(也就是说,使用 delete),
有另外的两件事情会发生:一个或多个析构函数在这些内存上被调用,然
后内存被回收 (通过一个被称为 operator delete 的函数——参见 Item
51)。对于 delete 来说有一个大问题:在要被删除的内存中究竟驻留有
多少个对象?这个问题的答案将打算有多少个析构函数必需被调用。
事实上,问题很简洁:将要被删除的指针是指向一个单一的对象还是
一个对象的数组?这是一个关键的问题,由于单一对象的内存布局通常
同于数组的内存布局。具体地说,一个数组的内存布局通常包含数组的大
小,这样可以使得 delete 更简单知道有多少个析构函数需要被调用。而
一个单一对象的内存中缺乏这个信息。你可以认为不同的内存布局看起来
如下列图,那个 n 就是数组的大小:
这固然只是一个例子。编译器并不是必需这样实现,虽然许多是这样
的。
当你对一个指针使用 delete,delete 知道是否有数组大小信息的方
法就是由你来告知它。假如你在你使用的 delete 中参加了方括号,
delete 就假设那个指针指向的是一个数组。否则,就假设指向一个单一
的对象。
std::string *stringPtr1 = new std::string;
std::string *stringPtr2 = new std::string[100];
...
delete stringPtr1; // delete an object
delete [] stringPtr2; // delete an array of objects
假如你对 stringPtr1 使用了 [] 形式会发生什么呢?结果是未定
义的,但不太可能是什么好事。假设如上图的布局,delete 将读入某些
内存的内容并将其看作一个数组的大小,然后开头调用那么多析构函数,
不仅全然不顾它在其上工作的内存不是数组,而且还可能忘掉了它正忙着
析构的对象的类型。
假如你对 stringPtr2 没有使用 [] 形式会发生什么呢?也是未定
义的,只不过你不会看到它会引起过多的析构函数被调用。此外,对于类
似 int 的内建类型其结果也是未定义的 (而且有时是有害的),即使这样
的类型没有析构函数。
规章很简洁。假如你在 ne 表达式中使用了 [],你也必需在相应的
delete 表达式中使用 []。假如你在 ne 表达式中没有使用 [],在匹配
的 delete 表达式中也不要使用 []。
当你写的一个类中包含一个指向动态安排的内存的指针,而且供应了
多个构造函数的时候,这条规章尤其重要,应镌刻脑海,由于那时你必需
当心地在全部的构造函数中使用一样形式的 ne 初始化那个指针成员。
假如你不这样做,你怎么知道在你的析构函数中应当使用哪种形式的
delete 呢?
这个规章对于有 typedef 倾向的人也很值得注目,由于这意味着一
个 typedef 的必需在文档中记录:当用 ne 生成一个 typedef 类型的
对象时,应当使用哪种形式的 delete。例如,考虑这个 typedef:
typedef std::stringAddressLines[4]; // a person’s address has
4 lines,
// each of which is a string
由于 AddressLines 是一个数组,这里使用 ne ,
std::string *pal =
原创力文档


文档评论(0)