zoukankan      html  css  js  c++  java
  • 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了。

  • 相关阅读:
    深入理解javascript原型和闭包(5)——instanceof
    深入理解javascript原型和闭包(4)——隐式原型
    启动mongodb的方式
    继承的几种方式
    npm install express 安装失败
    npm insta --savell和npm install --save-dev的区别
    express笔记之一安装
    mongoVUE安装配置
    nodejs笔记之一简介
    nodejs配置之二NPM配置之gulp使用时出现的错误
  • 原文地址:https://www.cnblogs.com/kanite/p/8315426.html
Copyright © 2011-2022 走看看