很多人听说过标准auto_ptr智能指针机制,但并不是每个人都天天使用它。这真是个遗憾,因为auto_ptr优雅地解决了C++设计和编码中常见的问题,正确地使用它可以生成健壮的代码。本文阐述了如何正确运用auto_ptr来让你的代码更加安全——以及如何避免对auto_ptr危险但常见的误用,这些误用会引发间断性发作、难以诊断的bug。 
.为什么称它为“自动”指针? 
auto_ptr只是众多可能的智能指针之一。许多商业库提供了更复杂的智能指针,用途广泛而令人惊异,从管理引用的数量到提供先进的代理服务。可以把标准C++ auto_ptr看作智能指针的Ford Escort(elmar注:可能指福特的一种适合家居的车型):一个简易、通用的智能指针,它不包含所有的小技巧,不像专用的或高性能的智能指针那么奢华,但是它可以很好的完成许多普遍的工作,它很适合日常性的使用。 
auto_ptr所做的事情,就是动态分配对象以及当对象不再需要时自动执行清理。这里是一个简单的代码示例,没有使用auto_ptr所以不安全:  // 示例 1(a): 原始代码 // 
void f() { 
T* pt( new T );
 /*...更多的代码...*/
 delete pt; 

我们大多数人每天写类似的代码。如果f()函数只有三行并且不会有任何意外,这么做可能挺好的。但是如果f()从不执行delete语句,或者是由于过早的返回,或者是由于执行函数体时抛出了异常,那么这个被分配的对象就没有被删除,从而我们产生了一个经典的内存泄漏。 
能让示例1(a)安全的简单办法是把指针封装在一个“智能的”类似于指针的对象里,这个对象拥有这个指针并且能在析构时自动删除这个指针所指的对象。因为这个智能指针可以简单的当成一个自动的对象(这就是说,它出了作用域时会自动毁灭),所以很自然的把它称之为“智能”指针:  // 示例 1(b): 安全代码, 使用了auto_ptr // 
void f() { 
auto_ptr<T> pt( new T );  /*...更多的代码...*/ 
}  // 酷: 当pt出了作用域时析构函数被调用, // 从而对象被自动删除 
现在代码不会泄漏T类型的对象,不管这个函数是正常退出还是抛出了异常,因为pt的析构函数总是会在出栈时被调用。清理会自动进行。 
最后,使用一个auto_ptr就像使用一个内建的指针一样容易,而且如果想要“撤销”资源,重新采用手动的所有权,我们只要调用release():  // 示例 2: 使用一个 auto_ptr // 
void g() { 
T* pt1 = new T; 
// 现在,我们有了一个分配好的对象 
// 将所有权传给了一个auto_ptr对象//
auto_ptr<T> pt2( pt1 ); 
// 使用auto_ptr就像我们以前使用简单指针一样
 *pt2 = 12; // 就像 "*pt1 = 12;" 
pt2->SomeFunc(); // 就像 "pt1->SomeFunc();" // 
用get()来获得指针的值 
assert( pt1 == pt2.get() );  // 用release()来撤销所有权 T* pt3 = pt2.release(); 
// 自己删除这个对象,因为现在
 // 没有任何auto_ptr拥有这个对象 
delete pt3; 
} // pt2不再拥有任何指针,所以不要 // 试图删除它...ok,不要重复删除 
最后,我们可以使用auto_ptr的reset()函数来重置auto_ptr使之拥有另一个对象。如果这个auto_ptr已经拥有了一个对象,那么,它会先删除已经拥有的对象,因此调用reset()就如同销毁这个auto_ptr,然后新建一个并拥有一个新对象: 
// 示例 3: 使用reset() //  void h() { 
auto_ptr<T> pt( new T() ); 
pt.reset( new T() ); 
// 删除由"new T(1)"分配出来的第一个T } // 最后,pt出了作用域, // 第二个T也被删除了

最新文章

  1. MySQL基础
  2. error-unable-to-access-the-iis-metabase或者无法加载VS项目中的网站
  3. Javascript Math.ceil()与Math.round()与Math.floor()区别
  4. caffe使用
  5. iOS开发-pod install 出错 The dependency `AFNetworking (~&gt; 2.6.0)` is not used in any concrete target.
  6. LaTeX测试
  7. Linux系统新手学习的11点建议
  8. restful风格,restcontroller与controller
  9. DIV布局之道三:DIV块的覆盖,DIV层遮盖其他DIV
  10. mongo 多条件 查询
  11. CSS各种选择器
  12. Windows API 之 CreateThread、WaitForSingleObject(未完)
  13. c#上课总结
  14. TensorFlow - 在 windows 系统上安装
  15. strace参数
  16. 第26月第26天 Domain=AVFoundationErrorDomain Code=-11850
  17. Echarts调整图表上下左右的间距,Echarts调整柱状图左右的间距
  18. 【bzoj4337】【Bjoi2015】树的同构
  19. PetaLinux安装及使用
  20. myeclipse如何取消对某个文件的验证

热门文章

  1. Java WeakHashMap 源码解析
  2. 通过百度获取IP地址对应的经纬度
  3. linux下ssh使用和配置
  4. top -Hp pid 显示所有的线程
  5. 部分实用的SQL语句
  6. File类学习笔记
  7. redis常见错误
  8. 百度2014校园招聘算法——给出一组数据A=[a_0, a_1, a-2, ... a_n](当中n可变),打印出该数值元素的全部组合。
  9. redis-2.6.16源码分析之pub-sub系统
  10. Android 4.2 通知通过PendingIntent启动Activity失败的问题