C++11 智能指针

  最近要使用C++11的智能指针,补充下博客。

  参考博客:https://www.cnblogs.com/wxquare/p/4759020.html

  重要文档:http://en.cppreference.com/w/cpp/memory/shared_ptr

    1、std::shared_ptr

    shared_ptr是一个模板类,封装了普通的指针,增加了一个引用计数。每一个shared_ptr的拷贝都指向相同的内存,在最后一个shared_ptr析构时,内存才会被释放。这样一个类也是可以模拟实现的。

 1 template <typename T>  
 2 class SmartPointer {  
 3 public:  
 4     //构造函数  
 5 SmartPointer(T* p=0): _ptr(p), _reference_count(new size_t){  
 6         if(p)  
 7             *_reference_count = 1;   
 8         else  
 9             *_reference_count = 0;   
10     }  
11     //拷贝构造函数  
12     SmartPointer(const SmartPointer& src) {  
13         if(this!=&src) {  
14             _ptr = src._ptr;  
15             _reference_count = src._reference_count;  
16             (*_reference_count)++;  
17         }  
18     }  
19     //重载赋值操作符  
20     SmartPointer& operator=(const SmartPointer& src) {  
21         if(_ptr==src._ptr) {  
22             return *this;  
23         }  
24         releaseCount();  
25         _ptr = src._ptr;  
26         _reference_count = src._reference_count;  
27         (*_reference_count)++;  
28         return *this;  
29     }  
30   
31     //重载操作符  
32     T& operator*() {  
33         if(ptr) {  
34             return *_ptr;  
35         }  
36         //throw exception  
37     }  
38     //重载操作符  
39     T* operator->() {  
40         if(ptr) {  
41             return _ptr;  
42         }  
43         //throw exception  
44     }  
45     //析构函数  
46     ~SmartPointer() {  
47         if (--(*_reference_count) == 0) {  
48             delete _ptr;  
49             delete _reference_count;  
50         }  
51      }  
52 private:  
53     T *_ptr;  
54         size_t *_reference_count;  
55         void releaseCount() {  
56         if(_ptr) {  
57             (*_reference_count)--;  
58                 if((*_reference_count)==0) {  
59                     delete _ptr;  
60                     delete _reference_count;  
61                 }  
62         }  
63         }  
64 };  
65   
66 int main()   
67 {  
68     SmartPointer<char> cp1(new char('a'));  
69     SmartPointer<char> cp2(cp1);  
70     SmartPointer<char> cp3;  
71     cp3 = cp2;  
72     cp3 = cp1;  
73     cp3 = cp3;  
74     SmartPointer<char> cp4(new char('b'));  
75     cp3 = cp4;  
76 }  
View Code

  内存模型图示:

    

       有这个图上面那个代码就容易理解多了。

  利用std::shared_ptr封装堆上内存,每一个shared_ptr的拷贝都指向相同的内存。在最后一个shared_ptr析构的时候,内存才会被释放。这机制就跟Java一模一样了,Java里参数传递说起来是两种,其实只有一种那就是值传递,Java参数传递分基础类型和引用类型,基础类型不用说就是值拷贝,引用类型其实也是值拷贝,拷贝的是对象地址,所以Java的参数传递像值传递又有地址传递的本质功能。

  2、std::unique_ptr

  unique_ptr也是封装一个内存,但不允许unique_ptr拷贝,就是始终只有一个unique_ptr对象指向一个内存块,不存在多个unique_ptr指向一个内存的情况。提供std::move函数完成指针移动。到现在也没想到std::unique_ptr有什么独特应用。

  3、std::weak_ptr

  weak_ptr指向一块内存,但不增加这个内存的引用计数。解决shared_ptr互相应用时造成无法删除内存的情况。

  4、利用智能指针封装管理第三方库分配的内存

  关于这点,参见博客:https://www.cnblogs.com/qicosmos/p/3889996.html    祁宇 著. 深入应用C++11:代码优化与工程级应用 

 

  在Qt项目工程里(我使用的是Qt5.6),要使用指针指针时,需要包含头文件#include <memory> ,不要写错成#include <memory.h>这是两个不同的文件,如果写成后面一个就会出现string in namespace std does not name a type(补充一句,STL的头文件全是不带.h的)。另外对C++11的支持也要看编译器,如果你的项目里可以使用nullptr,那么基本判断你的编译器支持C++11了。

 

posted @ 2018-01-19 09:43  kanite  阅读(327)  评论(0编辑  收藏  举报