第二十八课 再论智能指针(下)

多个智能指针指向同一片堆空间的需求是巨大的。

计数变量也是在堆空间里面定义的,它的生命周期和对象的生命周期相同。

添加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

 ==和!=重载为全局的。

智能指针使用军规:

 小结:

原文地址:https://www.cnblogs.com/wanmeishenghuo/p/9653005.html