首页 > 代码库 > 《Effective C++》学习笔记——条款16

《Effective C++》学习笔记——条款16

***************************************转载请注明出处:http://blog.csdn.net/lttree********************************************




三、Resource Management

 

 

Rule 16:Use the same form in corresponding use of new and delete

规则 16:成对使用 new 和 delete 时要采用相同的形式




1.现象

先看下下面动作有什么错?

<span style="font-size:14px;">std::string* stringArray = new std::string[100];
...
delete stringArray;</span>

所有的东西看起来都不错( 使用了 new 创建,并且也用 delete 进行了释放 ),BUT ,还是能找出错误:程序行为不明确。也就是说,stringArray所含有的100个元素,可能有99个没有被适当的消除,因为它们的析构函数没有被调用。

2.一些基本

当我们使用 new 时,会发生两件事:

①. 内存被分配出来 ( 通过名为 operator new 的函数 )

②. 针对此内存会有一个(或更多) 构造函数被调用。

当我们使用 delete 时,也会发生两件事:

①. 针对此内存会有一个(或更多)析构函数被调用。

②. 然后 此内存 才会被释放( 通过 operator delete 的函数)

关于delete的最大的问题在于: 即将被删除的内存之内究竟存有多少对象,这个问题的答案也决定了 有多少个析构函数必须被调用起来。

让问题更简单一些:即将被删除的指针,指向单一对象 还是 对象数组?

单一对象:Object

对象数组:n ObjectObject Object...



3.我来告诉它

当你对着一个指针使用 delete , 唯一能够告诉它,你删除的是一个对象还是对象数组的办法就是: 你自己来说。

如果使用 delete 时 加上中括号(方括号),delete便认定指针指向 数组对象,否则就是一个对象

std::string* stringPtr1 = new std::string;
std::string* stringPtr2 = new std::string[100];
...
delete stringPtr1;    // 删除一个对象
delete [ ] stringPtr2;    // 删除对象数组

或许你会问,如果它们反过来用呢?

如果你对 stringPtr1 使用 "delete [ ] "形式,delete会读取若干的内存,把它当做 数组大小 ,然后不停调用析构函数,肯定会出一些错误,而且是不可预知的。

如果对 stringPtr2 使用 delete,之前也提到过,100个对象,只有1个被释放,造成内存的浪费。

△ 其实,new 和 delete 的游戏规则 非常简单—— 如果调用 new 时,用了 [ ] ,你必须在对应调用delete时 使用 [ ] ; 如果 调用 new 时,没用[ ] ,你也不应该在用 delete时用 [ ]。


4.其他,还有啥?

这个规则,还要注意的就是 使用 typedef 的人。 它们要说清楚, 程序员用 new 创建该种 typedef类型对象时,该用哪种delete来删除。

typedef std::string AddressLines[4];    // 每个人的地址有四行,每行类型都是 string
由于 AddressLines是个数组,如果这样用new:

std::string* pal = new AddressLines;    // 它返回一个 string*对象

它相当于: new string[4]

所以,必须匹配的delete是:

delete pal;    // 这样就错了!
delete [ ] pal;    // 这样才对
总结: 这样很难以知道,我们应该用哪种delete形式,所以,为了避免这样的错误,最好尽量不要 对数组形式 进行 typedef动作。 这也很容易去更改,因为C++标准程序库 含有 string、vector这样的 template


5.请记住

★ 如果你在 new 表达式中使用[],必须在相应的delete表达式中也是用[]。如果你在 new 表达式中,不使用[],一定不要在相应的delete表达式中使用[]。


***************************************转载请注明出处:http://blog.csdn.net/lttree********************************************

《Effective C++》学习笔记——条款16