文章目录

  • 1 auto_ptr使用介绍
  • 2 auto_ptr的弊端

1 auto_ptr使用介绍

auto_ptr 是c++ 98定义的智能指针模板,其定义了管理指针的对象,可以将new 获得(直接或间接)的地址赋给这种对象。当对象过期时,其析构函数将使用delete 来释放内存!

使用建议:

  1. 尽可能不要将auto_ptr 变量定义为全局变量或指针。
  2. 除非自己知道后果,不要把auto_ptr 智能指针赋值给同类型的另外一个智能指针。
  3. C++11 后auto_ptr 已经被“抛弃”,已使用unique_ptr替代!

示例代码如下:

#include <iostream>
#include <string>
#include  <exception>
#include <memory>using namespace std;//auto_ptr< Test> t(new Test());  //忠告1: 智能指针不要定义为全局变量class Test
{public:Test() {cout << "Test is construct" << endl;debug = 1; }~Test() { cout << "Test is destruct" << endl; }int getDebug() {return debug;}private:int debug;
};//用  法:    auto_ptr<类型> 变量名(new 类型)void memory_leak_demo1() {auto_ptr< Test> t(new Test());//忠告3: 除非自己知道后果,不要把auto_ptr 智能指针赋值给同类型的另外一个智能指针//auto_ptr< Test> t1;//t1 = t;//auto_ptr<Test>* tp = new auto_ptr<Test>(new Test()); //忠告2: 不要定义指向智能指针对象的指针变量//在使用智能指针访问对象时,使用方式和普通指针一样cout<< "-> debug: "<<t->getDebug()<< endl;cout << "* debug: " << (*t).getDebug() << endl;//Test* tmp = t.get();//cout << "get debug: " << tmp->getDebug() << endl;//release 取消指针指针对动态内存的托管,之前分配的内存必须手动释放//Test*  tmp = t.release();  //delete tmp; //reset 重置智能指针托管的内存地址,如果地址不一致,原来的会被析构掉//t.reset();t.reset(new Test());if(0){Test* t1 = new Test();t1->getDebug();}return;}int memory_leak_demo2() {//Test* t = new Test();auto_ptr< Test> t(new Test());/************************************************ 程序执行一段复杂的逻辑,假设尝试从一个必须存在* 的文件中读取某些数据,而文件此时不存在************************************************/{throw exception("文件不存在");}//delete t;return 0;
}int main()
{memory_leak_demo1();/*try {memory_leak_demo2();}catch (exception e) {cout << "catch exception: " << e.what() << endl;}*/system("pause");return 0;
}

auto_ptr的源码如下,虽然不能完全看懂还是贴在这里:

#if _HAS_AUTO_PTR_ETC
// CLASS TEMPLATE auto_ptr
template <class _Ty>
class auto_ptr;template <class _Ty>
struct auto_ptr_ref { // proxy reference for auto_ptr copyingexplicit auto_ptr_ref(_Ty* _Right) : _Ref(_Right) {}_Ty* _Ref; // generic pointer to auto_ptr ptr
};template <class _Ty>
class auto_ptr { // wrap an object pointer to ensure destruction
public:using element_type = _Ty;explicit auto_ptr(_Ty* _Ptr = nullptr) noexcept : _Myptr(_Ptr) {}auto_ptr(auto_ptr& _Right) noexcept : _Myptr(_Right.release()) {}auto_ptr(auto_ptr_ref<_Ty> _Right) noexcept {_Ty* _Ptr   = _Right._Ref;_Right._Ref = nullptr; // release old_Myptr      = _Ptr; // reset this}template <class _Other>operator auto_ptr<_Other>() noexcept { // convert to compatible auto_ptrreturn auto_ptr<_Other>(*this);}template <class _Other>operator auto_ptr_ref<_Other>() noexcept { // convert to compatible auto_ptr_ref_Other* _Cvtptr = _Myptr; // test implicit conversionauto_ptr_ref<_Other> _Ans(_Cvtptr);_Myptr = nullptr; // pass ownership to auto_ptr_refreturn _Ans;}template <class _Other>auto_ptr& operator=(auto_ptr<_Other>& _Right) noexcept {reset(_Right.release());return *this;}template <class _Other>auto_ptr(auto_ptr<_Other>& _Right) noexcept : _Myptr(_Right.release()) {}auto_ptr& operator=(auto_ptr& _Right) noexcept {reset(_Right.release());return *this;}auto_ptr& operator=(auto_ptr_ref<_Ty> _Right) noexcept {_Ty* _Ptr   = _Right._Ref;_Right._Ref = 0; // release oldreset(_Ptr); // set newreturn *this;}~auto_ptr() noexcept {delete _Myptr;}_NODISCARD _Ty& operator*() const noexcept {#if _ITERATOR_DEBUG_LEVEL == 2_STL_VERIFY(_Myptr, "auto_ptr not dereferencable");
#endif // _ITERATOR_DEBUG_LEVEL == 2return *get();}_NODISCARD _Ty* operator->() const noexcept {#if _ITERATOR_DEBUG_LEVEL == 2_STL_VERIFY(_Myptr, "auto_ptr not dereferencable");
#endif // _ITERATOR_DEBUG_LEVEL == 2return get();}_NODISCARD _Ty* get() const noexcept {return _Myptr;}_Ty* release() noexcept {_Ty* _Tmp = _Myptr;_Myptr    = nullptr;return _Tmp;}void reset(_Ty* _Ptr = nullptr) noexcept { // destroy designated object and store new pointerif (_Ptr != _Myptr) {delete _Myptr;}_Myptr = _Ptr;}private:_Ty* _Myptr; // the wrapped object pointer
};

2 auto_ptr的弊端

auto_ptr是用于C++11之前的智能指针。由于 auto_ptr 基于排他所有权模式:两个指针不能指向同一个资源,复制或赋值都会改变资源的所有权。auto_ptr 主要有如下几个问题:

  • 复制和赋值会改变资源的所有权,不符合人的直觉。
  • 在 STL 容器中使用auto_ptr存在重大风险,因为容器内的元素必需支持可复制(copy constructable)和可赋值(assignable)。
  • 不支持对象数组的操作。
#include <stdio.h>
#include <iostream>
#include <string>
#include <memory>
#include <vector>using namespace std;int main() {//弊端1. auto_ptr 被C++11 抛弃的主要理由 p1= p2 ,复制或赋值都会改变资源的所有权auto_ptr<string> p1(new string("I 'm martin."));auto_ptr<string> p2(new string("I 'm rock."));printf("p1: %p\n", p1.get());printf("p2: %p\n", p2.get());p1 = p2;printf("after p1 = p2\n");printf("p1: %p\n", p1.get());printf("p2: %p\n", p2.get());//弊端2. 在 STL 容器中使用auto_ptr存在重大风险,因为容器内的元素必需支持可复制(copy constructable)和可赋值(assignable)。vector<auto_ptr<string>> va;auto_ptr<string> p3(new string("I 'm p3."));auto_ptr<string> p4(new string("I 'm p4."));va.push_back(std::move(p3));va.push_back(std::move(p4));cout <<"va[0]: "<< *va[0] << endl;cout <<"va[1]: "<< *va[1] << endl;//风险来啦va[0] = va[1];cout << "va[0]: " << *va[0] << endl;cout << "va[1]: " << *va[1] << endl;//弊端3. 不支持对象数组的内存管理//auto_ptr<int[]> ai(new int[5]);  //不能这样定义//auto_ptr 陷阱,不能把同一段内存交给多个auto_ptr 变量去管理/*{auto_ptr<string> p2;string* str = new string("智能指针的内存管理陷阱");p2.reset(str);{auto_ptr<string> p1;p1.reset(str);}cout <<"str: " << *p2 << endl;}*/system("pause");return 0;
}

所以,C++11用更严谨的unique_ptr 取代了auto_ptr!


参考资料:

  1. C/C++从入门到精通-高级程序员之路【奇牛学院】

auto_ptr使用介绍相关推荐

  1. 智能指针auto_ptr介绍

    我们大家都知道,new一定要和delete配合使用,但是有一种情况可能会使这种配对失效,如下程序: #include <iostream> using namespace std; cla ...

  2. C++——auto_ptr与unique_ptr

    auto_ptr与unique_ptr的比较 先介绍unique_ptr(独占智能指针)参考爱编程的大丙 std::unique_ptr 是一个独占型的智能指针,它不允许其他的智能指针共享其内部的指针 ...

  3. C++智能指针剖析(上)std::auto_ptr与boost::scoped_ptr

    1. 引入 C++语言中的动态内存分配没有自动回收机制,动态开辟的空间需要用户自己来维护,在出函数作用域或者程序正常退出前必须释放掉. 即程序员每次 new 出来的内存都要手动 delete,否则会造 ...

  4. unique_ptr使用介绍

    文章目录 1 unique_ptr使用介绍 1.1 unique_ptr的特性 1.2 unique_ptr常用方法介绍 1 unique_ptr使用介绍 1.1 unique_ptr的特性 我们先来 ...

  5. 浅谈auto_ptr智能指针

    引入智能指针: 智能指针的实现原理: 资源分配即初始化RAII(Resource Acquisition Is Initialization): 定义一个类来封装资源的分配和释放,在构造函数完成资源的 ...

  6. C++智能指针详解(auto_ptr、unique_ptr、shared_ptr)

    文章目录 1. 智能指针的应用场景 2. 智能指针的介绍 3. 智能指针的使用与原理 3.1 auto_ptr 3.2 unique_ptr 3.3 shared_ptr 3.4 shared_ptr ...

  7. C++的智能指针auto_ptr、unique_ptr源码解析

    C++的智能指针auto_ptr.unique_ptr源码解析 1.前言 2.源码准备 3.源码解析 3.1.auto_ptr解析 3.2.unique_ptr解 3.3.unique_ptr的一个偏 ...

  8. C++著名类库和C++标准库介绍

    C++著名类库 1.C++各大有名库的介绍--C++标准库  2.C++各大有名库的介绍--准标准库Boost  3.C++各大有名库的介绍--GUI  4.C++各大有名库的介绍--网络通信  5. ...

  9. C++版本发展简史:新特性介绍

    简介   C++是一门以C为基础发展而来的一门面向对象的高级程序设计语言,从1983年由Bjarne Stroustrup教授在贝尔实验室创立开始至今,已有30多个年头.C++从最初的C with c ...

最新文章

  1. 第十七届全国大学生智能车竞赛完全模型组 I 型车模数据
  2. python单词大全-学Python必须背的42个常见单词
  3. 综合布线成数据中心建设和运营的重要课题
  4. python结束线程池正在运行的线程_python之线程与线程池
  5. Redis实现消息队列的4种方案
  6. Loadrunner-web资源相关图表
  7. 第一节:ASP.NET开发环境配置
  8. Struts2.3.5+Hibernate3+Spring3.1基于注解实现的多文件上传,下载
  9. C/C++ 指针详解
  10. 装修材料石膏线品牌加盟类织梦模板
  11. Spring :Sprin体系
  12. java lc ctype_postgresql中的 LC_CTYPE、LC_COLLATE
  13. 插入排序---直接插入排序算法(Javascript版)
  14. android m3u8合成ts,M3U8-TS文件合并为MP4文件
  15. 10000亿的暴利:数字化营销今生与未来
  16. 微信公众号排版教程 | 你真的学会了排版么?
  17. Node.Js实现最最最简单的登录注册
  18. NLP(五十二)抽取式词义消歧(WSD)
  19. PyTorch 入门:训练一个深度神经网络(DNN)
  20. 邮件协议rfc822文档

热门文章

  1. mysql热备份还原_利用xtrabackup完成mysql的热备份与还原
  2. 【控制】《复杂运动体系统的分布式协同控制与优化》-方浩老师-第5章-多欧拉-拉格朗日系统分布式编队跟踪控制
  3. 【控制】《多无人机协同控制技术》周伟老师-第1章-无人机协同控制技术概述
  4. 4.3 Siamese 网络-深度学习第四课《卷积神经网络》-Stanford吴恩达教授
  5. 1.13 梯度检验-深度学习第二课《改善深层神经网络》-Stanford吴恩达教授
  6. Android 重新编译资源文件
  7. 基于MATLAB的Okumura-Hata模型的仿真
  8. 经典技术文章翻译(1):COM+集成:.NET Enterprise Services 如何帮你建立分布式应用(2)
  9. B-树和B+树的应用:数据搜索和数据库索引
  10. 史上最详细“截图”搭建Hexo博客——For Windows