【1】资源共享型智能指针实现方式简述
资源共享型的智能指针有两种实现方式:一种是侵入式;一种是非侵入式。
网上以及书籍比较常见的是非侵入式的,它的实现完全放在智能指针模板类内。
模板类有一个用于保存资源类对象的指针变量和一个用于记录资源对象引用计数的指针变量。
两者是所有的智能指针对象共享的,所以通过指针保存。
侵入式则不同,它的实现分散在智能指针模板和使用资源对象类中:
模板类只有一个用于保存资源对象的指针变量,资源对象的引用计数却放在资源对象类中。
非侵入式智能指针,它的引用计数变量为了保证所有对象共享,需要用堆里的内存。
因此需要用new,其实这点两者都一样,不一样的是使用new的次数。
侵入式智能指针的引用计数变量保存在资源对象内,因为对象是唯一的,所以引用计数也是唯一的。
相比非侵入式智能指针,侵入式智能指针的利弊:
优点:
1> 一个资源对象无论被多少个侵入式智能指针包含,从始至终只有一个引用计数变量。
不需要在每一个使用智能指针对象的地方都new一个计数对象,这样子效率比较高,使用内存也比较少,且比较安全;
2> 因为引用计数存储在资源对象本身,所以在函数调用的时候可以直接传递资源对象地址,而不用担心引用计数值丢失。
(非侵入式智能指针对象的拷贝,必须带着智能指针模板,否则就会出现对象引用计数丢失)。
缺点:
1> 资源对象类必须有引用计数变量,并且该变量的增减允许被侵入式智能指针模板类操作。
2> 如果该资源类对象并不没有必要使用智能指针时,它还是会带着引用计数变量。
【2】侵入式智能指针实现
1>实现代码如下:
1 #include <iostream>
2 using namespace std;
3
4 template< class T >
5 class smartPtr
6 {
7 public:
8 smartPtr(T* ptr)
9 {
10 m_ptr = ptr;
11 if (m_ptr != NULL)
12 m_ptr->AddRef();
13 }
14 smartPtr(const smartPtr<T>& spObj)
15 {
16 m_ptr = spObj.m_ptr;
17 if (m_ptr)
18 m_ptr->AddRef();
19 }
20 ~smartPtr()
21 {
22 if (m_ptr != NULL)
23 {
24 m_ptr->Release();
25 m_ptr = NULL;
26 }
27 }
28
29 T* operator->() const
30 {
31 return m_ptr;
32 }
33
34 T* Get() const
35 {
36 return m_ptr;
37 }
38 private:
39 T* m_ptr;
40 };
41
42
43 class Int
44 {
45 public:
46 Int(int value) : m_nValue(value)
47 {
48 m_pCount = new int(0);
49 std::cout <<"Construct: "<<this<<std::endl;
50 }
51
52 ~Int()
53 {
54 std::cout <<"Destruct: "<<this<<std::endl;
55 }
56
57 void AddRef()
58 {
59 (*m_pCount)++;
60 }
61
62 void Release()
63 {
64 --(*m_pCount);
65 if ((*m_pCount) == 0)
66 {
67 delete this;
68 }
69 }
70
71 int GetCount()
72 {
73 return (*m_pCount);
74 }
75
76 private:
77 int* m_pCount;
78 int m_nValue;
79 };
80
81 void TestTwo(Int* ptr)
82 {
83 smartPtr<Int> spTemp = ptr;
84 std::cout<<spTemp->GetCount()<<" "<<spTemp.Get()<<std::endl; //计数为2
85 smartPtr<Int> spObj = spTemp;
86 std::cout<<spObj->GetCount()<<" "<<spTemp.Get()<<std::endl; //计数为3
87 }
88
89 void TestOne()
90 {
91 Int* pInt = new Int(10);
92 smartPtr<Int> spInt = pInt;
93 std::cout<<spInt->GetCount()<<" "<<spInt.Get()<<std::endl; //计数为1
94 TestTwo(pInt);
95 std::cout<<spInt->GetCount()<<" "<<spInt.Get()<<std::endl; //计数为1
96 }
97
98 void main()
99 {
100 TestOne();
101 }
102
103 //执行结果如下:
104 /*
105 Construct: 009749E0
106 1 009749E0
107 2 009749E0
108 3 009749E0
109 1 009749E0
110 Destruct: 009749E0
111 */
以上为不完整代码实现,仅仅为了理解侵入式智能指针而已。
Good Good Study, Day Day Up.
顺序 选择 循环 总结