博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
C++——智能指针shared_ptr的实现
阅读量:5327 次
发布时间:2019-06-14

本文共 8150 字,大约阅读时间需要 27 分钟。

  1. 起初,我最直观的设计想法,直接设计一个类:包含全部要素(对象,指针计数)。然后提供出去。

 

1 class CPoint 2 { 3   public: 4     CPoint(int xVal = 0, int yVal = 0) : x(xVal), y(yVal) {} 5     int getX() const { return x; } 6     int getY() const { return y; } 7     void setX(int xVal) { x = xVal; } 8     void setY(int yVal) { y = yVal; } 9 10   private:11     int x, y;12 };13 14 class CSmartPtr15 {16   public:17     CSmartPtr(CPoint *ptr) : m_pPoint(ptr),m_count(1) {}18     CSmartPtr(const CSmartPtr &sptr) : m_pPoint(sptr.m_pPoint),m_count(sptr.m_count) {}19 20     ~CSmartPtr()21     {22         Release();23     }24     CPoint* get()25     {26         return m_pPoint;27     }28 /*此处不知道如何有效实现,既能提供出去,有把内部清空????*/29     CPoint *release()30     {31         m_count = 0;32         return m_pPoint;33     }34     int user_count() { return m_count; }35     CPoint &operator*()36     {37         return *(m_pPoint);38     }39 40     CPoint *operator->()41     {42         return m_pPoint;43     }44 45   private:46     void Release()47     {48         if (m_count-- == 0)49         {50             delete m_pPoint;51         }52         else53         {54             cout << "引用次数:" << m_count << endl;55         }56     }57 58     int m_count;59     CPoint *m_pPoint;60 };

 

但是我实现到release方法的时候,并不能满足需求。因为release方法的要求是,交出对象的控制权,然后智能指针指向null;Releases ownership of its , by returning its value and replacing it with a null pointer.这就尴尬了。因此采用了将指针计数和对象单独拿出来的做法,也就是网上其他博客中常见的做法。但我还不是很理解他们那种做法的解释。

 

      代码实现:

 

1 class CPoint  2 {  3   public:  4     CPoint(int xVal = 0, int yVal = 0) : x(xVal), y(yVal) {}  5     int getX() const { return x; }  6     int getY() const { return y; }  7     void setX(int xVal) { x = xVal; }  8     void setY(int yVal) { y = yVal; }  9  10   private: 11     int x, y; 12 }; 13 class CSmartPtr; 14 /* 15  16 */ 17 class CCountPtr 18 { 19     private: 20         friend class CSmartPtr; 21         int m_count; 22         CPoint *m_pPoint; 23         CCountPtr(CPoint *ptr):m_pPoint(ptr),m_count(1){} 24         ~CCountPtr() 25         { 26             m_count=0; 27         } 28 }; 29  30 class CSmartPtr 31 { 32     public: 33       CSmartPtr(CPoint *ptr) : m_pCountPtr (new CCountPtr(ptr)){} 34       CSmartPtr(const CSmartPtr &sptr) : m_pCountPtr(sptr.m_pCountPtr) {} 35       CSmartPtr& operator=(const CSmartPtr &sptr) 36       { 37           (sptr.m_pCountPtr->m_count)++; 38           minusOne(); 39           m_pCountPtr = sptr.m_pCountPtr; 40           return *this; 41       } 42       ~CSmartPtr()  43       { 44           minusOne(); 45       } 46       CPoint *get() 47       { 48           return m_pCountPtr->m_pPoint; 49       } 50       CPoint *release() 51       { 52           CPoint *pRet = m_pCountPtr->m_pPoint; 53           m_pCountPtr->m_pPoint = nullptr; 54           m_pCountPtr->m_count  = 0; 55           return pRet; 56       } 57       /*Destroys the object currently managed by the unique_ptr (if any) and takes ownership of p.*/ 58       void reset(CPoint *pPoint) 59       { 60           minusOne(); 61           m_pCountPtr = new CCountPtr(pPoint); 62       } 63       void swap(CSmartPtr &x) 64       { 65           CPoint *pRet = m_pCountPtr->m_pPoint; 66           int count = m_pCountPtr->m_count; 67  68           m_pCountPtr->m_pPoint = x.m_pCountPtr->m_pPoint; 69           m_pCountPtr->m_count = x.m_pCountPtr->m_count; 70  71           x.m_pCountPtr->m_pPoint = pRet; 72           x.m_pCountPtr->m_count = count; 73       } 74  75       int user_count(){
return m_pCountPtr->m_count; } 76 CPoint& operator *() 77 { 78 return *(m_pCountPtr->m_pPoint); 79 } 80 81 CPoint* operator ->() 82 { 83 return m_pCountPtr->m_pPoint; 84 } 85 86 private: 87 void minusOne() 88 { 89 if (m_pCountPtr->m_count-- == 0) 90 { 91 delete m_pCountPtr; 92 m_pCountPtr = nullptr; 93 } 94 else 95 { 96 cout << "引用次数:" << m_pCountPtr->m_count << endl; 97 } 98 } 99 CCountPtr *m_pCountPtr;100 };101 102 int main()103 {104 CPoint *pPoint = new CPoint(3,4);105 {106 CSmartPtr sptr1(pPoint);107 {108 (*sptr1).setX(10);109 cout<<"initial:"<
getX(): " << sptr1->getX() << endl;111 CPoint *pPoint2 = new CPoint(5, 6);112 /*测试swap*/113 cout << "swap:" << endl;114 CPoint *pPoint4 = new CPoint(30, 40);115 CSmartPtr sptr2(pPoint4);116 sptr1.swap(sptr2);117 cout << "sptr1->getX(): " << sptr1->getX() << endl;118 cout << "sptr2->getX(): " << sptr2->getX() << endl;119 /*测试reset*/120 cout << "reset:" << endl;121 sptr1.reset(pPoint2);122 cout << "sptr1->getX(): " << sptr1->getX() << endl;123 /*测试release*/124 cout << "release:" << endl;125 CPoint *pPoint3 = new CPoint(30, 40);126 pPoint3 = sptr1.release();127 cout << "pPoint3->getX(): " << pPoint3->getX() << endl;128 cout << "sptr1.count: " << sptr1.user_count() << endl;129 }130 cout<<"sptr1.count: "<< sptr1.user_count()<
getX()<

 

 

       2.模板类。改进一下即可。将CPoint换成泛型表达。

1 template 
2 class CSmartPtr; 3 4 template
5 class CCountPtr 6 { 7 private: 8 friend class CSmartPtr
; 9 int m_count; 10 T *m_pT; 11 CCountPtr(T *ptr) : m_pT(ptr), m_count(1) {} 12 ~CCountPtr(){} 13 }; 14 15 template
16 class CSmartPtr 17 { 18 public: 19 CSmartPtr(T *ptr) : m_pCountPtr (new CCountPtr
(ptr)){} 20 CSmartPtr(const CSmartPtr &sptr) : m_pCountPtr(sptr.m_pCountPtr) {} 21 CSmartPtr& operator=(const CSmartPtr &sptr) 22 { 23 (sptr.m_pCountPtr->m_count)++; 24 minusOne(); 25 m_pCountPtr = sptr.m_pCountPtr; 26 return *this; 27 } 28 29 ~CSmartPtr() 30 { 31 minusOne(); 32 } 33 T * get() 34 { 35 return m_pCountPtr->m_pPoint; 36 } 37 T *release() 38 { 39 T *pRet = m_pCountPtr->m_pPoint; 40 m_pCountPtr->m_pPoint = nullptr; 41 m_pCountPtr->m_count = 0; 42 return pRet; 43 } 44 /*Destroys the object currently managed by the unique_ptr (if any) and takes ownership of p.*/ 45 void reset(T *pPoint) 46 { 47 minusOne(); 48 m_pCountPtr = new CCountPtr
(pPoint); 49 } 50 void swap(CSmartPtr &x) 51 { 52 T *pRet = m_pCountPtr->m_pPoint; 53 int count = m_pCountPtr->m_count; 54 55 m_pCountPtr->m_pPoint = x.m_pCountPtr->m_pPoint; 56 m_pCountPtr->m_count = x.m_pCountPtr->m_count; 57 58 x.m_pCountPtr->m_pPoint = pRet; 59 x.m_pCountPtr->m_count = count; 60 } 61 62 int user_count(){ return m_pCountPtr->m_count; } 63 64 T& operator *() 65 { 66 return *(m_pCountPtr->m_pT); 67 } 68 69 T* operator ->() 70 { 71 return m_pCountPtr->m_pT; 72 } 73 74 private: 75 void minusOne() 76 { 77 if (m_pCountPtr->m_count-- == 0) 78 { 79 delete m_pCountPtr; 80 m_pCountPtr = nullptr; 81 } 82 else 83 { 84 cout << "引用次数:" << m_pCountPtr->m_count << endl; 85 } 86 } 87 CCountPtr
*m_pCountPtr; 88 }; 89 90 /*这里使用了参数包,我对此不是很熟悉,直接copy的代码*/ 91 template
92 inline CSmartPtr
93 make_smart(Args&&... args) 94 { 95 return CSmartPtr
(new T(std::forward
(args)...)); 96 } 97 98 int main() 99 {100 int b=10;101 int* a=&b;102 {103 CSmartPtr
sptr1(a);104 {105 cout << "*sptr1: " << *sptr1 << endl;106 CSmartPtr
sptr2 = sptr1;107 108 cout << "*sptr2: " << *sptr2 << endl;109 110 CSmartPtr
sptr3 = make_smart
(20);111 cout << "*sptr3: " << *sptr3 << endl;112 }113 cout<<"sptr1.count: "<< sptr1.user_count()<

 

 

以上为智能指针shared_ptr的实现过程,还是有很多东西要学习的。

 

以下为参考网站,以至于很多东西都是直接拿过来的,感谢!

https://www.cnblogs.com/QG-whz/p/4777312.html

 http://www.cplusplus.com/reference/memory/unique_ptr/unique_ptr/

https://liam.page/2018/01/13/smart-pointer/

转载于:https://www.cnblogs.com/whutao/p/10623539.html

你可能感兴趣的文章
关于 linux 的 limit 的设置
查看>>
HDU(4528),BFS,2013腾讯编程马拉松初赛第五场(3月25日)
查看>>
vim中文帮助教程
查看>>
MySQL基础3
查看>>
RxJS & Angular
查看>>
面向对象(多异常的声明与处理)
查看>>
MTK笔记
查看>>
ERROR: duplicate key value violates unique constraint "xxx"
查看>>
激活office 365 的启动文件
查看>>
无法根据中文查找
查看>>
[简讯]phpMyAdmin项目已迁移至GitHub
查看>>
转载 python多重继承C3算法
查看>>
【题解】 bzoj1597: [Usaco2008 Mar]土地购买 (动态规划+斜率优化)
查看>>
css文本溢出显示省略号
查看>>
git安装和简单配置
查看>>
面向对象:反射,双下方法
查看>>
鼠标悬停提示文本消息最简单的做法
查看>>
课后作业-阅读任务-阅读提问-2
查看>>
面向对象设计中private,public,protected的访问控制原则及静态代码块的初始化顺序...
查看>>
fat32转ntfs ,Win7系统提示对于目标文件系统文件过大解决教程
查看>>