第17条:以独立语句将new创建的对象存储在智能指针中
2014-12-12 21:18
176 查看
假设有一个函数用来显示处理程序的优先级,另一个函数根据当前优先级为一个动态分配的 Widget 做一些处理:
int priority(); void processWidget(std::tr1::shared_ptr<Widget> pw, int priority);
谨记“以对象管理资源”(参见第 13 条)。 processWidget 中可以使用智能指针来动态分配其需要处理的 Widget 。
下面是对 progressWidget 的一次调用:
processWidget(new Widget, priority());
请稍等,这样调用将不会通过编译。 tr1::shared_ptr 的构造函数中包含了一个 explicit 的裸指针(rawpointer),于是便不存在从“ new Widget ”语句返回的裸指针到 processWidget 所需的 tr1::shared_ptr 的隐式转换。然而下边的代码将顺利通过编译:
processWidget(std::tr1::shared_ptr<Widget>(new Widget),priority());
看上去有些令人吃惊,虽然在此我们使用“对象来管理资源”,上述调用却可能泄漏资源。后面会详细解释。
编译器产生一个 processWidget 调用之前,它必须评估传入的各实参。第二个参数仅仅调用了一个函数 priority ,但是第一个参数(“ std::tr1::shared_ptr<Widget>(newWidget) ”)包含两部分:
1、运行 “new Widget”表达式
2、调用 tr1::shared_ptr 的构造函数
因此,在调用processWidget之前,编译器必须创建代码解决下面的三件事情: 1、调用 priority 。 、执行 “new Widget” 。 3、调用 tr1::shared_ptr 构造函数。
C++编译器对这三项任务完成顺序要求宽松。(这一点与Java和C#不同,这两门语言中的函数参数总是以一个特定的顺序得到评估。)由于“ new Widget ”语句为 tr1::shared_ptr 的构造函数传递了一个参数,因此它必须在 tr1::shared_ptr 的构造函数被调用之前得到执行。但是调用 priority 的工作可以放到第一,第二,也可以放在最后。如果编译器决定第二个处理它(这样可以使代码更高效),我们就会得到这样的执行序列: 1. 执行 “ new Widget ” . 2. 调用 priority 。 3. 调用 tr1::shared_ptr 的构造函数。
但是如果调用 priority 时抛出了一个异常,将会发生些什么?在这种情况下,由于“ new Widget ”返回的指针不会如愿保存在 tr1::shared_ptr 中,于是内存泄漏就发生了。在“资源被创建”和“资源被转换为资源管理对象”这段时间内,有如果发生异常,那么调用 processWidget 就会造成资源泄漏。 防止这类问题办法简单:使用单独的语句,1、创建Widget 并存入一个智能指针,2、把智能指针传递给 processWidget :
<pre name="code" class="cpp">std::tr1::shared_ptr<Widget> pw(new Widget); // 在一个单独的语句中创建 Widget 并存入一个智能指针 processWidget(pw, priority()); // 这样调用就不会内存泄漏。
这样可行,因为编译器为“多行的语句安排执行顺序”要比“单一语句”严格得多。在这段改进的代码中,“ new Widget ”语句以及对 tr1::shared_ptr 的构造函数的调用在单独的语句中,对 priority 的调用在另一个单独的语句中,所以编译器就没有机会调换处理顺序了。
需要记住的: 在单独的语句中使用智能指针来保存由new创建的对象(以独立语句将new创建的对象存储于智能指针内)。否则,在异常时发生时会资源泄漏。
相关文章推荐
- C++中为什么需要将new对象通过独立语句置入智能指针
- [翻译] Effective C++, 3rd Edition, Item 17: 在 standalone statements(独立语句)中将 new 出来的 objects(对象)存入 smart pointers(智能指针)
- 条款17 以独立语句将new对象置入智能指针
- Effective C++第17条:要在单独的语句中使用智能指针来存储由new创建的对象
- 【翻译】[Effective C++第三版•中文版][第17条]要在单独的语句中使用智能指针来存储由new创建的对象
- Effective C++第17条:要在单独的语句中使用智能指针来存储由new创建的对象
- 以独立的语句将new对象置入智能指针
- effective c++ Item 17: 在一个独立的语句中将 new 出来的对象存入智能指针
- 读书笔记_Effective_C++_条款十七:以独立语句将new产生的对象置入智能指针
- Effective C++ 条款17 以独立语句将newed对象置入智能指针
- effective c++ 条款17 :以独立语句将newed 对象置入智能指针
- 条款17:以独立语句将newed对象置入智能指针
- Effective C++(17) 以独立语句将newed对象置入智能指针
- 条款17:以独立语句将newed对象置入智能指针
- 条款17:以独立语句将newed的对象置入智能指针
- 改善C++ 程序的150个建议学习之建议34:用智能指针管理通过new创建的对象
- [Effective C++ --017]以独立语句将newed对象置入智能指针
- Effective C++ 学记之17 以独立语句将newed对象置入智能指针
- 条款17:以独立语句将NEWED对象置入智能指针
- 条款17:以独立语句将newed对象置入智能指针