首先,如果你不知道什么是智能指针,请先移步:C++智能指针简单剖析

1.auto_ptr

  1. #ifndef AUTO_PTR_H
  2. #define AUTO_PTR_H
  3.  
  4. template<typename T>
  5. class auto_ptr
  6. {
  7. public :
  8. //使用explicit关键字避免隐式转换
  9. explicit auto_ptr(T* p=);
  10. ~auto_ptr();
  11.  
  12. //使用另一个类型兼容的auto_ptr来初始化一个新的auto_ptr
  13. template<typename U>
  14. auto_ptr(auto_ptr<U>& rhs);
  15.  
  16. template<typename U>
  17. auto_ptr<T>& operator=(auto_ptr<U>& rhs);
  18.  
  19. T& operator*() const;
  20. T* operator->() const;
  21.  
  22. //返回原始对象的指针
  23. T* get() const;
  24. //放弃指针的所有权
  25. T* release();
  26. //删除原有指针并获得指针p的所有权
  27. void reset(T* p=);
  28.  
  29. private:
  30. T* pointee;
  31. };
  32.  
  33. template<typename T>
  34. auto_ptr<T>::auto_ptr(T* p)
  35. :pointee(p)
  36. {}
  37.  
  38. template<typename T>
  39. auto_ptr<T>::~auto_ptr()
  40. {
  41. delete pointee; //如果所有权被转移了,我们会将指针置0,delete空指针不会发生任何事
  42. }
  43.  
  44. template<typename T>
  45. template<typename U>
  46. auto_ptr<T>::auto_ptr(auto_ptr<U>& rhs)
  47. :pointee(rhs.release()) //转交所有权,即rhs将所有权转交给this,并将自身指针置0
  48. {}
  49.  
  50. template<typename T>
  51. template<typename U>
  52. auto_ptr<T>& auto_ptr<T>::operator=(auto_ptr<U>& rhs)
  53. {
  54. if(this!=&rhs)
  55. reset(rhs.release());
  56. return *this;
  57. }
  58.  
  59. template<typename T>
  60. T& auto_ptr<T>::operator*() const
  61. {
  62. return *pointee;
  63. }
  64.  
  65. template<typename T>
  66. T* auto_ptr<T>::operator->() const
  67. {
  68. return pointee;
  69. }
  70.  
  71. template<typename T>
  72. T* auto_ptr<T>::get() const
  73. {
  74. return pointee;
  75. }
  76.  
  77. template<typename T>
  78. T* auto_ptr<T>::release()
  79. {
  80. T* oldpointee=pointee;
  81. pointee=; //置NULL
  82. return oldpointee; //交出所有权
  83. }
  84.  
  85. template<typename T>
  86. void auto_ptr<T>::reset(T* p)
  87. {
  88. if(pointee!=p)
  89. {
  90. delete pointee; //删除原有的
  91. pointee=p; //设置新的
  92. }
  93. }
  94.  
  95. #endif
  1.  

2.shared_ptr

实现原理:

当多个shared_ptr管理同一个指针,仅当最后一个shared_ptr析构时,指针才被delete。为实现这一点,我们需要一个引用计数(reference counting)。引用计数指的是,所有管理同一个裸指针(raw pointer)的shared_ptr,都共享一个引用计数器,每当一个shared_ptr被赋值(或拷贝构造)给其它shared_ptr时,这个共享的引用计数器就加1,当一个shared_ptr析构或者被用于管理其它裸指针时,这个引用计数器就减1,如果此时发现引用计数器为0,那么说明它是管理这个指针的最后一个shared_ptr了,于是我们释放指针指向的资源。

在底层实现中,这个引用计数器保存在某个内部类型里(这个类型中还包含了deleter,它控制了指针的释放策略,默认情况下就是普通的delete操作),而这个内部类型对象在shared_ptr第一次构造时以指针的形式保存在shared_ptr中。shared_ptr在赋值和拷贝构造另一个shared_ptr时,这个指针被另一个shared_ptr共享。在引用计数归零时,这个内部类型指针与shared_ptr管理的资源一起被释放。此外,为了保证线程安全性,引用计数器的加1,减1操作都是原子操作,它保证shared_ptr由多个线程共享时不会出问题。

下面看看一个例子:

shared_ptr 是引用计数型(reference counting)智能指针,它在堆(heap)上放了个计数值(count)。shared_ptr 包含两个成员,一个是指向 Foo 的指针 ptr,另一个是 ref_count 指针(不一定是原始指针,有可能是 class 类型),指向堆上的 ref_count 对象。ref_count 对象有多个成员,具体的数据结构如图所示,其中 use_count为我们所说的计数,deleter 和 allocator 是可选的。

shared_ptr安全级别:

  • 一个 shared_ptr 对象实体可被多个线程同时读取;

  • 两个 shared_ptr 对象实体可以被两个线程同时写入,“析构”算写操作;

  • 如果要从多个线程读写同一个 shared_ptr 对象,那么需要加锁。

具体的代码实现这里不涉及,有兴趣的朋友可以去看一看boost的实现~

C++ 智能指针 auto_ptr 和 shared_ptr的更多相关文章

  1. C++智能指针 auto_ptr、shared_ptr、weak_ptr和unique_ptr

    手写代码是理解C++的最好办法,以几个例子说明C++四个智能指针的用法,转载请注明出处. 一.auto_ptr auto_ptr这是C++98标准下的智能指针,现在常常已经被C++标准的其他智能指针取 ...

  2. 聊聊智能指针 auto_ptr、shared_ptr、weak_ptr和unique_ptr

    本文为转载:https://www.cnblogs.com/zeppelin5/p/10083597.html,对作者有些地方做了修正. 手写代码是理解C++的最好办法,以几个例子说明C++四个智能指 ...

  3. 初次窥见智能指针auto_ptr和shared_ptr

    #include <memory>//shared_ptr要用的头文件 using namespace std; class A //测试auto_ptr和shared_ptr的delet ...

  4. 关于智能指针auto_ptr

    智能指针auto_ptr和shared_ptr也是面试中经常被问到的一个 感觉看auto_ptr的源码反而更加容易理解一些,因为源码的代码量并不大,而且比较容易理解. 本篇主要介绍auto_ptr 其 ...

  5. 智能指针auto_ptr & shared_ptr

    转载:智能指针auto_ptr 很多人听说过标准auto_ptr智能指针机制,但并不是每个人都天天使用它.这真是个遗憾,因为auto_ptr优雅地解决了C++设计和编码中常见的问题,正确地使用它可以生 ...

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

    智能指针(auto_ptr) 这个名字听起来很酷是不是?其实auto_ptr 只是C++标准库提供的一个类模板,它与传统的new/delete控制内存相比有一定优势,但也有其局限.本文总结的8个问题足 ...

  7. 自己动手实现智能指针auto_ptr

    面试的时候,我们经常会被问到如何自己动手实现智能指针auto_ptr.今天我就一边参考STL库中的源代码,一边将auto_ptr的实现敲一遍. auto_ptr归根到底是一个模版类,那么这个类要实现哪 ...

  8. C++ 智能指针auto_ptr

    template<class T> class auto_ptr { public: ); // Item M5 有“explicitfor”// 的描述 template<clas ...

  9. C++中的智能指针(auto_ptr)

    实际上auto_ptr 仅仅是C++标准库提供的一个类模板,它与传统的new/delete控制内存相比有一定优势.使用它不必每次都手动调用delete去释放内存.当然有利也有弊,也不是全然完美的. 本 ...

随机推荐

  1. 我的PCB电路设计(一)

    我的制板规则 过孔大小:14/24mil-(12/22-28/50)  一般过孔没必要太大.如果电流较大可以适当增大过孔,或者多加几个过孔 线宽大小:小信号线8mil,大电流线不等按1A电流30mil ...

  2. 安装 docker-compose

    安装Docker-Compose之前,请先安装 python-pip,安装好pip之后,就可以安装Docker-Compose了. 一.检查是否已经安装 二.安装 docker-compose 1.安 ...

  3. 新概念英语(1-129)Seventy miles an hour

    Lesson 129 Seventy miles an hour 时速70英里 Listen to the tape then answer this question. What does Ann ...

  4. LXC学习实践(3)快速体验第一个容器

    1.搭建第一个 LXC 虚拟计算机 #yum install lxc* 2.安装软件包后要检查 Linux 发行版的内核对 LXC 的支持情况,可以使用下面命令 #lxc-checkconfig #l ...

  5. SpringCloud的注解:汇总篇

    使用注解之前要开启自动扫描功能,如下配置中base-package为需要扫描的包(含子包): 1 <context:component-scan base-package="cn.te ...

  6. DOM常用外部插入方法与区别

    1.DOM外部插入after()与before() 节点与节点之前有各种关系,除了父子,祖辈关系,还可以是兄弟关系.之前我们在处理节点插入的时候,接触到了内部插入的几个方法,这节我们开始讲外部插入的处 ...

  7. CNN中减少网络的参数的三个思想

    CNN中减少网络的参数的三个思想: 1) 局部连接(Local Connectivity) 2) 权值共享(Shared Weights) 3) 池化(Pooling) 局部连接 局部连接是相对于全连 ...

  8. mysql新建表设置为utf8

    CREATE DATABASE IF NOT EXISTS yourdbname DEFAULT CHARSET utf8 COLLATE utf8_general_ci;

  9. 线程的同步控制(Synchronization)

    临界区(Critical Sections) 摘要 临界区(Critical Section) 用来实现"排他性占有".适合范围时单一进程的各线程之间. 特点 一个局部对象,不是一 ...

  10. 五,前端---关于JS的点滴

    一:异常抛出 try,catch,throw 例如: function myFunction(){ try{ var x = document.getElementBy('demo').value; ...