第二十八课 再论智能指针(下)
Posted wanmeishenghuo
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了第二十八课 再论智能指针(下)相关的知识,希望对你有一定的参考价值。
多个智能指针指向同一片堆空间的需求是巨大的。
计数变量也是在堆空间里面定义的,它的生命周期和对象的生命周期相同。
添加SharedPointer.h文件:
1 #ifndef SHAREDPOINTER_H 2 #define SHAREDPOINTER_H 3 4 #include <cstdlib> 5 #include "Pointer.h" 6 #include "Exception.h" 7 8 namespace DTLib 9 { 10 11 template < typename T > 12 class SharedPointer : public Pointer<T> 13 { 14 protected: 15 int* m_ref; 16 17 void assign(const SharedPointer<T>& obj) 18 { 19 this->m_ref = obj.m_ref; 20 this->m_pointer = obj.m_pointer; 21 22 if( this->m_ref ) 23 { 24 (*this->m_ref)++; 25 } 26 } 27 28 public: 29 SharedPointer(T& p = NULL) : m_ref(NULL) 30 { 31 if( p ) 32 { 33 this->m_ref = static_cast<int*>(std::malloc(sizeof(int))); 34 35 if( this->m_ref ) 36 { 37 *(this->m_ref) = 1; 38 this->m_pointer = p; 39 } 40 else 41 { 42 THROW_EXCEPTION(NoEnoughMemoryException, "No memory to create SharesPointer object ..."); 43 } 44 } 45 } 46 47 SharedPointer(const SharedPointer<T>& obj) 48 { 49 assign(obj); 50 } 51 52 SharedPointer<T>& operator= (const SharedPointer<T>& obj) 53 { 54 if( this != &obj ) 55 { 56 clear(); //先将当前智能指针置空 57 58 assign(obj); 59 } 60 61 return *this; 62 } 63 64 void clear() 65 { 66 T* toDel = this->m_pointer; 67 int* ref = this->m_ref; 68 69 this->m_pointer = NULL; 70 this->m_ref = NULL; 71 72 if( ret ) 73 { 74 (*ref)--; //当前指针指向的堆空间计数减1 75 76 if( *ref == 0 ) 77 { 78 free(ref); 79 80 delete toDel; 81 } 82 } 83 } 84 85 ~SharedPointer() 86 { 87 clear(); 88 } 89 }; 90 91 } 92 93 #endif // SHAREDPOINTER_H
测试程序如下:
1 #include <iostream> 2 #include "SharedPointer.h" 3 4 using namespace std; 5 using namespace DTLib; 6 7 8 class Test : public Object 9 { 10 public: 11 int value; 12 13 Test() : value(0) 14 { 15 cout << "Test()" << endl; 16 } 17 18 ~Test() 19 { 20 cout << "~Test()" << endl; 21 } 22 }; 23 24 int main() 25 { 26 SharedPointer<Test> sp0 = new Test(); 27 SharedPointer<Test> sp1 = sp0; 28 SharedPointer<Test> sp2 = NULL; 29 30 sp2 = sp1; 31 32 cout << sp0->value << endl; 33 cout << sp1->value << endl; 34 cout << sp2->value << endl; 35 36 return 0; 37 }
运行结果如下:
第二个测试程序:
1 #include <iostream> 2 #include "SharedPointer.h" 3 4 using namespace std; 5 using namespace DTLib; 6 7 8 class Test : public Object 9 { 10 public: 11 int value; 12 13 Test() : value(0) 14 { 15 cout << "Test()" << endl; 16 } 17 18 ~Test() 19 { 20 cout << "~Test()" << endl; 21 } 22 }; 23 24 int main() 25 { 26 SharedPointer<Test> sp0 = new Test(); 27 SharedPointer<Test> sp1 = sp0; 28 SharedPointer<Test> sp2 = NULL; 29 30 sp2 = sp1; 31 32 sp2->value = 100; 33 34 cout << sp0->value << endl; 35 cout << sp1->value << endl; 36 cout << sp2->value << endl; 37 38 return 0; 39 }
结果如下:
一个堆空间被三个指针指向,最终只释放一次。
编译警告:
提示我们要在SharedPointer的拷贝构造函数中显式的调用父类的拷贝构造函数。
最终的SharedPointer.h内容如下:
1 #ifndef SHAREDPOINTER_H 2 #define SHAREDPOINTER_H 3 4 #include <cstdlib> 5 #include "Pointer.h" 6 #include "Exception.h" 7 8 namespace DTLib 9 { 10 11 template < typename T > 12 class SharedPointer : public Pointer<T> 13 { 14 protected: 15 int* m_ref; 16 17 void assign(const SharedPointer<T>& obj) 18 { 19 this->m_ref = obj.m_ref; 20 this->m_pointer = obj.m_pointer; 21 22 if( this->m_ref ) 23 { 24 (*this->m_ref)++; 25 } 26 } 27 28 public: 29 SharedPointer(T* p = NULL) : m_ref(NULL) 30 { 31 if( p ) 32 { 33 this->m_ref = static_cast<int*>(std::malloc(sizeof(int))); 34 35 if( this->m_ref ) 36 { 37 *(this->m_ref) = 1; 38 this->m_pointer = p; 39 } 40 else 41 { 42 THROW_EXCEPTION(NoEnoughMemoryException, "No memory to create SharesPointer object ..."); 43 } 44 } 45 } 46 47 SharedPointer(const SharedPointer<T>& obj) : Pointer<T>(NULL) 48 { 49 assign(obj); 50 } 51 52 SharedPointer<T>& operator= (const SharedPointer<T>& obj) 53 { 54 if( this != &obj ) 55 { 56 clear(); //先将当前智能指针置空 57 58 assign(obj); 59 } 60 61 return *this; 62 } 63 64 void clear() 65 { 66 T* toDel = this->m_pointer; 67 int* ref = this->m_ref; 68 69 this->m_pointer = NULL; 70 this->m_ref = NULL; 71 72 if( ref ) 73 { 74 (*ref)--; //当前指针指向的堆空间计数减1 75 76 if( *ref == 0 ) 77 { 78 free(ref); 79 80 delete toDel; 81 } 82 } 83 } 84 85 ~SharedPointer() 86 { 87 clear(); 88 } 89 }; 90 91 template < typename T > 92 bool operator ==(const SharedPointer<T>& l, const SharedPointer<T>& r) 93 { 94 return (l.get() == r.get()); 95 } 96 97 template < typename T > 98 bool operator !=(const SharedPointer<T>& l, const SharedPointer<T>& r) 99 { 100 return !(l == r); 101 } 102 103 } 104 105 #endif // SHAREDPOINTER_H
==和!=重载为全局的。
智能指针使用军规:
小结:
以上是关于第二十八课 再论智能指针(下)的主要内容,如果未能解决你的问题,请参考以下文章