作者:LogM
本文原载于 https://segmentfault.com/u/logm/articles,不允许转载~
3. 资源管理
-
3.1 条款13:使用"资源管理类"管理资源
- 对于 new 出来的对象,某些意外情况下 delete 没有被执行(代码遗漏、鲁棒性低或者出现异常),导致资源泄漏。作者建议使用智能指针管理 new 出来的对象。
-
auto_ptr
在拷贝或者赋值时,新指针获得资源拥有权,旧指针变为null。
std::auto_ptr<Investment> pInv1(createInvestment()); //pInv1获得资源拥有权 std::auto_ptr<Investment> pInv2(pInv1); //pInv2获得资源拥有权,pInv1变null pInv1 = pInv2; //pInv1获得资源拥有权,pInv2变null
-
shared_ptr
使用计数的方式来确定有哪些指针在使用该资源,计数为0释放资源。它的拷贝和赋值则没有auto_ptr
的那个问题。
-
3.2 条款14:在资源管理类中小心拷贝行为
- 接3.1,在某些不适用"智能指针"的场景,需要自定义"资源管理类"来管理资源,作者建议需要考虑下这个类的拷贝和赋值。
-
3.3 条款15:在"资源管理类"中提供对原始资源的访问
- 在3.1,我们使用智能指针管理对象,此时指针类型是
std::auto_ptr<Investment>
,但如果有个函数需要类型为Investment*
的参数怎么办呢? - 智能指针有
.get()
函数可以显式转换成原始指针;它们也重载了operator->
和operator*
,可以隐式转换。 - 类似的,自定义的"资源管理类"也需要考虑显示转换和隐式转换,提供对原始资源的访问。
- 在3.1,我们使用智能指针管理对象,此时指针类型是
-
3.4 条款16:成对使用new和delete时要采取相同形式
- 简单来说,就是
new
出来的对象要用delete
释放,new []
出来的对象要用delete []
释放。 -
new
出来的对象如果使用delete []
释放,将导致未定义的行为;new []
出来的对象如果用delete
释放,很可能只释放了数组的第一个元素。
- 简单来说,就是
-
3.5 条款17:以独立语句将对象置入智能指针
//假设有下面这个函数,它有两个参数,调用该函数时,会做下面三件事: //a. 调用new Widget //b. 执行shared_ptr的构造 //c. 执行priority() // //执行顺序是未定义的,可能为a->b->c,也可能a->c->b等等。注意,当顺序为a->c->b,且priority()抛出异常时,资源泄漏。 processWidget(std::shared_ptr<Widget>(new Widget), priority()); //解决方法:别偷懒,写成两句话 std::shared_ptr<Widget> pW(new Widget); processWidget(pW, priority());
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。