- 起初,我最直观的设计想法,直接设计一个类:包含全部要素(对象,指针计数)。然后提供出去。
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 template2 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/