zoukankan      html  css  js  c++  java
  • shared_ptr&scoped_ptr&weak_ptr

    RAII - Resource Acquisition Is Initialization

      获得一个资源的时候,不管这个资源是对象、内存、文件句柄或者其它什么,你都要在一个对象的构造函数中获得它, 并且在该对象的析构函数中释放它。当你创建资源的时候将它放入封装类对象构造函数(new出来的指针立即放入shared_ptr析造函数里), 当该对象离开作用域时,对象析构函数会自动销毁资源。

    shared_ptr

      在shard_ptr使用中经常会发现,一个对象会有两次被析构的情况。其实这种是因为那个对象指针被两次当成shard_ptr构造函数里的参数。一定要避免这种现象。考虑如下代码:

    1 {
    2     int* pInt = new int(14);
    3     boost::shared_ptr<int> temp1(pInt);
    4     assert(temp1.use_count() == 1);      // 用一个指针初始化temp1,temp1认为pInt只被它拥有。所以这个指针被引用1次
    5 
    6     boost::shared_ptr<int> temp2(pInt); // 用一个指针初始化temp2,temp2认为pInt只被它拥有。所以这个指针被引用1次
    7     assert(temp2.use_count() == 1);
    8 
    9     }   // temp1,temp2都离开作用域,它们都销毁pInt. pInt被销毁了两次!系统终于崩溃了 -_-

      正确的做法是将原始指针赋给智能指针后,以后的操作都要针对智能指针了.

    1 {
    2     boost::shared_ptr<int> temp1(new int(14)); // 资源获取即初始化
    3     assert(temp1.use_count() == 1);
    4 
    5     boost::shared_ptr<int> temp2(temp1);
    6     assert(temp2.use_count() == 2);
    7 
    8 }   // temp1,temp2都离开作用域,引用次数变为0,指针被销毁

      如果资源的创建销毁不是以new,delete的方式创建销毁怎么办?shared_ptr也可以指定删除器:

     1 // FileCloser.h FileCloser删除器  
     2 class FileCloser
     3 {
     4     public:
     5     void operator()(FILE *pf)
     6     {
     7         if (pf)
     8         {
     9           fclose(pf);
    10         }
    11     }
    12 };
    13 
    14 // 某实现文件
    15 {
    16     boost::shared_ptr<FILE> fp(fopen(pszConfigFile, "r"), FileCloser());    // 指定调用FileCloser函数对象销毁资源
    17 }

    weak_ptr

       weak_ptr必须用shared_ptr/weak_ptr初始化,用lock()获取指针。使用lock后,会返回一个shared_ptr的临时栈变量,把ptr引用计数加1,从而可以放心使用,而不用担心在使用过程中ptr会被其它线程给释放。

      

    引用计数管理

      shared_ptr、weak_ptr的引用计数管理可简化为,两种指针都内含同一个引用计数管理器,如下:

      

      refcount_为shared_ptr使用,weak_count_为weak_ptr使用。当shared_ptr构造时,refcount_+1,析构时refcount-1,并且检察weak_count_是否为0;当weak_ptr构造时,weak_count_+1,析构时weak_count_-1。

      当refcount_weak_count_均为0时,把controlblok删除。shared_ptr、weak_ptr成员变量均为如下结构。

      

    scoped_ptr

      scoped_ptr无法共享,无拷贝构造函数和赋值函数。用于局部使用。

  • 相关阅读:
    转数组
    字符串分割(分行)
    字符串操作:判断相等、判断首尾、大小写转换
    字符串操作:索引位置、去空格、替换字符串
    数组(遍历、转置、元素替换、排序、复制)
    专利申请教程
    循环语句
    条件语句
    输入
    h.264直接预测
  • 原文地址:https://www.cnblogs.com/tekkaman/p/3308624.html
Copyright © 2011-2022 走看看