首先,如果你不知道什么是智能指针,请先移步:C++智能指针简单剖析
1.auto_ptr
1 #ifndef AUTO_PTR_H
2 #define AUTO_PTR_H
3
4 template<typename T>
5 class auto_ptr
6 {
7 public :
8 //使用explicit关键字避免隐式转换
9 explicit auto_ptr(T* p=0);
10 ~auto_ptr();
11
12 //使用另一个类型兼容的auto_ptr来初始化一个新的auto_ptr
13 template<typename U>
14 auto_ptr(auto_ptr<U>& rhs);
15
16 template<typename U>
17 auto_ptr<T>& operator=(auto_ptr<U>& rhs);
18
19 T& operator*() const;
20 T* operator->() const;
21
22 //返回原始对象的指针
23 T* get() const;
24 //放弃指针的所有权
25 T* release();
26 //删除原有指针并获得指针p的所有权
27 void reset(T* p=0);
28
29 private:
30 T* pointee;
31 };
32
33 template<typename T>
34 auto_ptr<T>::auto_ptr(T* p)
35 :pointee(p)
36 {}
37
38 template<typename T>
39 auto_ptr<T>::~auto_ptr()
40 {
41 delete pointee; //如果所有权被转移了,我们会将指针置0,delete空指针不会发生任何事
42 }
43
44 template<typename T>
45 template<typename U>
46 auto_ptr<T>::auto_ptr(auto_ptr<U>& rhs)
47 :pointee(rhs.release()) //转交所有权,即rhs将所有权转交给this,并将自身指针置0
48 {}
49
50 template<typename T>
51 template<typename U>
52 auto_ptr<T>& auto_ptr<T>::operator=(auto_ptr<U>& rhs)
53 {
54 if(this!=&rhs)
55 reset(rhs.release());
56 return *this;
57 }
58
59 template<typename T>
60 T& auto_ptr<T>::operator*() const
61 {
62 return *pointee;
63 }
64
65 template<typename T>
66 T* auto_ptr<T>::operator->() const
67 {
68 return pointee;
69 }
70
71 template<typename T>
72 T* auto_ptr<T>::get() const
73 {
74 return pointee;
75 }
76
77 template<typename T>
78 T* auto_ptr<T>::release()
79 {
80 T* oldpointee=pointee;
81 pointee=0; //置NULL
82 return oldpointee; //交出所有权
83 }
84
85 template<typename T>
86 void auto_ptr<T>::reset(T* p)
87 {
88 if(pointee!=p)
89 {
90 delete pointee; //删除原有的
91 pointee=p; //设置新的
92 }
93 }
94
95 #endif
2.shared_ptr
实现原理:
当多个shared_ptr管理同一个指针,仅当最后一个shared_ptr析构时,指针才被delete。为实现这一点,我们需要一个引用计数(reference counting)。引用计数指的是,所有管理同一个裸指针(raw pointer)的shared_ptr,都共享一个引用计数器,每当一个shared_ptr被赋值(或拷贝构造)给其它shared_ptr时,这个共享的引用计数器就加1,当一个shared_ptr析构或者被用于管理其它裸指针时,这个引用计数器就减1,如果此时发现引用计数器为0,那么说明它是管理这个指针的最后一个shared_ptr了,于是我们释放指针指向的资源。
在底层实现中,这个引用计数器保存在某个内部类型里(这个类型中还包含了deleter,它控制了指针的释放策略,默认情况下就是普通的delete操作),而这个内部类型对象在shared_ptr第一次构造时以指针的形式保存在shared_ptr中。shared_ptr在赋值和拷贝构造另一个shared_ptr时,这个指针被另一个shared_ptr共享。在引用计数归零时,这个内部类型指针与shared_ptr管理的资源一起被释放。此外,为了保证线程安全性,引用计数器的加1,减1操作都是原子操作,它保证shared_ptr由多个线程共享时不会出问题。
下面看看一个例子:
shared_ptr 是引用计数型(reference counting)智能指针,它在堆(heap)上放了个计数值(count)。shared_ptr 包含两个成员,一个是指向 Foo 的指针 ptr,另一个是 ref_count 指针(不一定是原始指针,有可能是 class 类型),指向堆上的 ref_count 对象。ref_count 对象有多个成员,具体的数据结构如图所示,其中 use_count为我们所说的计数,deleter 和 allocator 是可选的。
shared_ptr安全级别:
-
一个 shared_ptr 对象实体可被多个线程同时读取;
-
两个 shared_ptr 对象实体可以被两个线程同时写入,“析构”算写操作;
-
如果要从多个线程读写同一个 shared_ptr 对象,那么需要加锁。
具体的代码实现这里不涉及,有兴趣的朋友可以去看一看boost的实现~
原文链接: https://www.cnblogs.com/ktao/p/7565157.html
欢迎关注
微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍
原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/260134
非原创文章文中已经注明原地址,如有侵权,联系删除
关注公众号【高性能架构探索】,第一时间获取最新文章
转载文章受原作者版权保护。转载请注明原作者出处!