std::shared_ptr 是通过指针保持对象共享所有权的智能指针。多个 shared_ptr 对象可占有同一对象大概实现了一下,主要实现原理为,共享指针内部持有堆资源的指针以及引用计数的指针,通过对这两个指针的维护,达到多个共享对象对同一资源的控制

  实现主要分为三个文件。share_ptr.h,smart_ptr_define.h, main.cpp  (编译平台:Linux centos 7.0 编译器:gcc 4.8.5 )

  1. //smart_ptr_define.h
  2. #ifndef __SMART_PTR_DEFINE_H__
  3. #define __SMART_PTR_DEFINE_H__
  4.  
  5. #include <assert.h>
  6.  
  7. #define PTR_ASSERT(x) assert(x)
  8.  
  9. #define _SMART_PTR_BEGIN namespace smartptr {
  10. #define _SMART_PTR_END }
  11. #define _SMART_PTR ::smartptr::
  12.  
  13. #endif

  主要实现文件share_ptr.h

  1. #ifndef __SHARE_PTR_H__
  2. #define __SHARE_PTR_H__
  3.  
  4. #include <iostream>
  5. #include "smart_ptr_define.h"
  6.  
  7. _SMART_PTR_BEGIN
  8.  
  9. template <class T>
  10. struct default_deleter
  11. {
  12. void operator()(T* ptr)
  13. {
  14. if (ptr != NULL)
  15. {
  16. delete ptr;
  17. ptr = NULL;
  18. }
  19. }
  20. };
  21.  
  22. template <class T, class deleter = default_deleter<T> >
  23. class shared_ptr
  24. {
  25. public:
  26. typedef shared_ptr<T, deleter> SHARE_PTR;
  27.  
  28. shared_ptr()
  29. {
  30. m_ptr = NULL;
  31. m_iRefCount = NULL;
  32. }
  33.  
  34. explicit shared_ptr(T* ptr)
  35. {
  36. if (ptr != NULL)
  37. {
  38. m_ptr = ptr;
  39. RefCountInit();
  40. }
  41. }
  42.  
  43. shared_ptr(deleter d, T* ptr)
  44. {
  45. if (ptr != NULL)
  46. {
  47. m_ptr = ptr;
  48. m_deleter = d;
  49. RefCountInit();
  50. }
  51. }
  52.  
  53. //拷贝构造
  54. shared_ptr(const SHARE_PTR& sh_ptr)
  55. {
  56. if (sh_ptr.m_ptr != NULL)
  57. {
  58. m_ptr = sh_ptr.m_ptr;
  59. m_deleter = sh_ptr.m_deleter;
  60. m_iRefCount = sh_ptr.m_iRefCount;
  61.  
  62. RefCountIncrease();
  63. }
  64. }
  65.  
  66. //赋值运算符
  67. SHARE_PTR& operator = (const SHARE_PTR& sh_ptr)
  68. {
  69. if (this != &sh_ptr)
  70. {
  71. RefCountDecrease();
  72.  
  73. if (sh_ptr.m_ptr != NULL)
  74. {
  75. m_ptr = sh_ptr.m_ptr;
  76. m_deleter = sh_ptr.m_deleter;
  77. m_iRefCount = sh_ptr.m_iRefCount;
  78.  
  79. RefCountIncrease();
  80. }
  81. }
  82.  
  83. return (*this);
  84. }
  85.  
  86. ~shared_ptr()
  87. {
  88. RefCountDecrease();
  89. }
  90.  
  91. public:
  92. //提领操作
  93. T& operator*()
  94. {
  95. PTR_ASSERT(m_ptr != NULL);
  96. return *(m_ptr);
  97. }
  98.  
  99. //原始指针操作
  100. T* operator->()
  101. {
  102. PTR_ASSERT(m_ptr != NULL);
  103. return m_ptr;
  104. }
  105.  
  106. operator bool() const
  107. {
  108. return m_ptr != NULL;
  109. }
  110.  
  111. //取得原始指针
  112. T* getPointer()
  113. {
  114. PTR_ASSERT(m_ptr != NULL);
  115. return m_ptr;
  116. }
  117.  
  118. //获得引用计数
  119. int getRefCount()
  120. {
  121. PTR_ASSERT(m_iRefCount != NULL);
  122. return *m_iRefCount;
  123. }
  124.  
  125. private:
  126. void RefCountInit()
  127. {
  128. m_iRefCount = new int();
  129. }
  130.  
  131. void RefCountIncrease()
  132. {
  133. if (m_iRefCount != NULL)
  134. {
  135. ++(*m_iRefCount);
  136. }
  137. }
  138.  
  139. void RefCountDecrease()
  140. {
  141. if (m_iRefCount != NULL && --(*m_iRefCount) == )
  142. {
  143. m_deleter(m_ptr);
  144. delete m_iRefCount;
  145. m_ptr = NULL;
  146. m_iRefCount = NULL;
  147. }
  148. }
  149.  
  150. private:
  151. int* m_iRefCount; //引用计数
  152.  
  153. T* m_ptr; //对象指针
  154.  
  155. deleter m_deleter; //删除器
  156. };
  157.  
  158. _SMART_PTR_END
  159. #endif // !__SHARE_PTR_H__

  main函数测试

  1. #include "share_ptr.h"
  2. #include <memory>
  3.  
  4. class Test
  5. {
  6. public:
  7. Test()
  8. {
  9. std::cout << "construct.." << std::endl;
  10. }
  11.  
  12. void method()
  13. {
  14. std::cout << "welcome Test.." << std::endl;
  15. }
  16.  
  17. ~Test()
  18. {
  19. std::cout << "destruct.." << std::endl;
  20. }
  21. };
  22.  
  23. int main()
  24. {
  25. Test* t1 = new Test();
  26.  
  27. _SMART_PTR shared_ptr<Test> shptr(t1);
  28.  
  29. _SMART_PTR shared_ptr<Test> shptr1(shptr);
  30.  
  31. _SMART_PTR shared_ptr<Test> shptr2 = shptr1;
  32.  
  33. std::cout << "RefCount: " << shptr2.getRefCount() << std::endl;
  34.  
  35. shptr2->method();
  36.  
  37. (*shptr2).method();
  38.  
  39. if (shptr2)
  40. {
  41. std::cout << "ptr is exit " << std::endl;
  42. }
  43.  
  44. return ;
  45. }

  测试最后打印:

  1. [yejy@yejy cmake-]$ ./smartptr
  2. construct..
  3. RefCount:
  4. welcome Test..
  5. welcome Test..
  6. ptr is exit
  7. destruct..
  8. [yejy@yejy cmake-]$

  shared_ptr主要需实现的功能点如下(以下总结引用自网络,非原创):

  1. 没有参数构造的时候,初始化为空,即对象和引用计数的两个指针都为0

  2. 使用指针为参数构造时,拥有此指针,在没有智能指针指向它时进行析构

  3. 智能指针复制时,两个智能指针共同拥有内部指针,引用计数同时+1

  4. 智能指针可以使用智能指针或普通指针重新赋值。重载=操作符,对于智能指针赋值,需要考虑是否自赋值,以避免将自身析构了后再重新赋值,而普通指针赋值给智能指针,则不需要考虑自赋值,因为两者本身是两个类型

  5. 获得底层指针的访问,定义getPtrPointer()getPtrCounter()来分别返回底层指针和引用计数,定义operator bool()来处理智能指针隐式转换为bool的情况

  6. 重载->×操作符 ,来实现与普通指针相同的指针访问

  7. 需要支持隐式指针类型转换,static_cast不支持而dynamic_cast支持的转换则使用Cast<T2>()成员函数来解决。考虑定义友元类,以防止指向派生类的智能指针有权限访问基类的内部对象;当转型不成功时,返回为空 (未实现)

  8. 如果一个裸指针直接用来创建两个智能指针的话,期望的情况是当两个智能指针析构掉的时候,该指针会被delete两次从而崩溃(这是shared_ptr的特点)

  9. 不处理循环引用(也是shared_ptr的特点),可以通过与weak_ptr协作来打破循环

  10. 实现deleter机制

智能指针之 shared_ptr的更多相关文章

  1. 智能指针之shared_ptr基本概述

    1.shared_ptr允许有多个指针指向同一个对象,unique_ptr独占所指向的对象. 2.类似于vector,智能指针也是模板.创建智能指针: shared_ptr<string> ...

  2. 【C++11新特性】 C++11智能指针之shared_ptr

    C++中的智能指针首先出现在“准”标准库boost中.随着使用的人越来越多,为了让开发人员更方便.更安全的使用动态内存,C++11也引入了智能指针来管理动态对象.在新标准中,主要提供了shared_p ...

  3. C++智能指针之shared_ptr与右值引用(详细)

    1. 介绍 在 C++ 中没有垃圾回收机制,必须自己释放分配的内存,否则就会造成内存泄露.解决这个问题最有效的方法是使用智能指针(smart pointer).智能指针是存储指向动态分配(堆)对象指针 ...

  4. C++ | 再探智能指针(shared_ptr 与 weak_ptr)

    上篇博客我们模拟实现了 auto_ptr 智能指针,可我们说 auto_ptr 是一种有缺陷的智能指针,并且在C++11中就已经被摈弃掉了.那么本章我们就来探索 boost库和C++11中的智能指针以 ...

  5. [5] 智能指针boost::shared_ptr

    [1]boost::shared_ptr简介 boost::shared_ptr属于boost库,定义在namespace boost中,包含头文件#include<boost/shared_p ...

  6. 关于智能指针boost::shared_ptr

    boost库中的智能指针shared_ptr, 功能强大, 且开销小,故受到广大coder的欢迎. 但在实际的使用过程中,笔者也发现了一些不足. 1.定制的删除器 shared_ptr除了可以使用默认 ...

  7. 智能指针(二):shared_ptr实现原理

    前面讲到auto_ptr有个很大的缺陷就是所有权的转移,就是一个对象的内存块只能被一个智能指针对象所拥有.但我们有些时候希望共用那个内存块.于是C++ 11标准中有了shared_ptr这样的智能指针 ...

  8. 【STL学习】智能指针之shared_ptr

    前面已经学习过auto_ptr,这里补充另外一种智能指针,比auto_ptr要更强力更通用的shared_ptr. shared_ptr 简介及使用选择  几乎所有的程序都需要某种形式的引用计数智能指 ...

  9. 智能指针auto_ptr & shared_ptr

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

随机推荐

  1. 《java入门第一季》之面向对象(抽象类其实不抽象)

    上一篇(http://blog.csdn.net/qq_32059827/article/details/51334198)对抽象类做了一些描述,这一篇根据两个案例加深一下印象.会觉得抽象类其实不抽象 ...

  2. 【一天一道LeetCode】#10. Regular Expression Matching

    一天一道LeetCode系列 (一)题目 Implement regular expression matching with support for '.' and '*'. '.' Matches ...

  3. 使用Multiplayer Networking做一个简单的多人游戏例子-1/3(Unity3D开发之二十五)

    猴子原创,欢迎转载.转载请注明: 转载自Cocos2Der-CSDN,谢谢! 原文地址: http://blog.csdn.net/cocos2der/article/details/51006463 ...

  4. LeetCode之“动态规划”:Best Time to Buy and Sell Stock I && II && III && IV

    Best Time to Buy and Sell Stock I 题目链接 题目要求: Say you have an array for which the ith element is the ...

  5. Linux进程管理 - PRI,nice,free,uname,netstat

    优先运行序 (priority, PRI) 这个 PRI 值越低代表越优先的意思.不过这个 PRI 值是由核心动态调整的, 使用者无法直接调整 PRI 值的. 由於 PRI 是核心动态调整的,我们使用 ...

  6. Unity PUN插件多人在线同步角色坐标旋转角度和动作

    用PUN插件的话,就在OnJoinedRoom()回调函数里,表示加入房间,可以实例化角色,GameObject go=PhotonNetwork.Instantiate(prefabPlayer.n ...

  7. obj-c编程12:复制对象

    好吧,上一篇我怎么也没想到会写那么多字那么少的代码,希望这一篇不会如此哦. 言归正传,对象的复制分为浅复制和深复制,前者只是复制对象的引用,当原对象的内容发生变化时,复制对象的内容也会发生变化,毕竟他 ...

  8. The table name must be enclosed in double quotation marks or sqare bracket while accessing EXCEL by

      1  Preface DB Query Analyzer is presented by Master Gen feng, Ma from Chinese Mainland. It has Eng ...

  9. obj-c编程15[Cocoa实例03]:MVC以及归档化示例

    前面的博文里介绍了归档和解档,这里我们把它实际应用到一个简单的代码中去,将它作为一个多文档应用程序的打开和保存的背后支持.另外这里介绍一下MVC思想,这个在任何语言里都会有,它是一种设计思想,主要可以 ...

  10. 自定义ViewGroup添加布局动画

    声明几个属性值: <declare-styleable name="GridImageViewGroup"> <attr name="childVert ...