zoukankan      html  css  js  c++  java
  • 引用计数

    什么是引用计数?

    一个在堆上创建的对象,记录有多少个指针指向它。


     为什么要设计引用计数,他解决什么问题?

    1、new出一个临时对象,使用完了,需要delete。但是拥有权会转移(auto_ptr)或者扩散,因此很难确定delete时机。忘记delete导致资源泄漏,过早delete,导致还在使用的指针出现错误,重复delete导致未定义行为。

    2、许多对象拥有相同的值,存储多次是个很愚蠢的事,可以共享。


    如何实现:

    1、以String为例说明,String s1 = "Hello", String s2 = s1; 可以让s1,s2共享"Hello"。

    2、引用计数放在哪里呢?显然不能放在String对象中,因为每个String对象都有这个引用计数,引用计数应该和String指向的Value在一起。

    3、在String中建立一个嵌套类StringValue,String中有一个字段 StringValue* pStringValue。为什么StringValue设计成嵌套类,因为StringValue只是嵌套在String中,为了实现String,不会出现在其他地方。与此类似的有,STL中各种容器专属的迭代器。

    4、StringValue中有:int refCount,记录引用计数。char* pData:指向char。

    5、String的copy构造

    1 String::String(const String& rhs)
    2     :pStringValue(rhs.pStringValue)
    3 {
    4     ++(pStringValue->refCount);
    5 }

    6、String的copy赋值

     1 String& String::operator =(const String& rhs)
     2 {
     3     if(pStringValue == rhs.pStringValue) //共享的数据赋值
     4     {
     5         return *this;
     6     }
     7     
     8     if(--pStringValue->refCount == 0) //处理老的内容
     9     {
    10         delete pStringValue;
    11     }
    12     
    13     pStringValue = rhs.pStringValue;
    14     ++pStringValue->refCount;
    15     
    16     return *this;
    17 }

    7、String的析构

    1 String::~String()
    2 {
    3     if(--pStringValue->refCount == 0)
    4     {
    5         delete pStringValue;
    6     }    
    7 }

    8、Copy-On-Write(写时才复制)

    考虑s1,s2指向同一个内容,s1[2] = f; 程序员期望只是修改s1,如何支持?

     1 char& operator[](int index)
     2 {
     3     if(this->pStringValue->refCount > 1) //存在其他人共享
     4     {
     5         --this->pStringValue->refCount;
     6         this->pStringValue = new StringValue(pStringValue->pData);
     7     }
     8     
     9     return pStringValue->pData[index];
    10 }

    9、考虑 char* pc = &s1[2]; 然后修改pc,还是会修改s2,怎么办?
      增加一个标志位,访问[],设置StringValue不是共享。

    10、现在假如Person,Book也有这种需求,怎么办?

      需要建立PersonValue,BookValue,通过建立基类,复用代码。RCValue为基类,RCValue 的copy构造和copy赋值,不需要做任何事,因为不会对RCValue调用copy构造和copy赋值。而是对String,Person,Book调用copy构造,copy赋值,传递pValue指针。

    11、对于String中的pStringValue使用smart point,可以实现自动操作引用计数。

  • 相关阅读:
    RuntimeError: cryptography is required for sha256_password or caching_sha2_p
    Django-C003-视图
    MySQL 实时监控日志
    ERROR 2003 (HY000): Can't connect to MySQL server on 'localhost' (10061) : 第一次设置MySQL也适用
    Django-C002-深入模型,到底有多深
    ubuntu16.04下安装&配置anaconda+tensorflow新手教程
    人脸算法系列:MTCNN人脸检测详解
    YOLO系列:YOLOv1,YOLOv2,YOLOv3,YOLOv4,YOLOv5简介
    python __getitem__()方法理解
    启动scala的方法
  • 原文地址:https://www.cnblogs.com/nzbbody/p/3454645.html
Copyright © 2011-2022 走看看