引用计数需要注意的几个地方

This is a trick worth knowing: nesting a struct in the private part of a class is a convenient way to give access to the struct to all the members of the class, but to deny access to everybody else (except, of course, friends of the class). 


引用计数的思考过程:

① 针对: std::cout << s[1]; s[2] = 'a'; 这两种情况无法分辨operator [] 是用作写还是读,提出 copy-on-write

② 针对: s1 = s; s2 = s; char* px = &s[0]; 如果px重新赋值,s1, s2将都被改写,提出增加一个share标志,

                  对于任何非const的operator[]操作,都将标志设为false,且无法恢复


几个需要说明的地方:

RCObject::RCObject(const RCObject&)
: refCount(0), shareable(true) {}
这个refCount为0,因为这是一个“构造函数”,一个新对象的refCount当然是0了。


RCObject& RCObject::operator=(const RCObject&)
{ return *this; }
这没有关于refCount的操作,因为这是“值”本身的相关操作,不是使用和封装这个值的类


1.复制构造函数

String& String::operator=(const String& rhs)
{
  if (value == rhs.value) {          // do nothing if the values
    return *this;                    // are already the same; this
  }                                  // subsumes the usual test of
                                     // this against &rhs (see Item E17)
  if (--value->refCount == 0) {      // destroy *this's value if
    delete value;                    // no one else is using it
  }
  value = rhs.value;                 // have *this share rhs's
  ++value->refCount;                 // value
  return *this;
}

2.. 指针、引用与写时拷贝

大部分情况下,写时拷贝可以同时保证效率和正确性。只有一个挥之不去的问题。看一下这样的代码:
String s1 = "Hello";
char *p = &s1[1];

char& String::operator[](int index)
{
  if (value->refCount > 1) {
    --value->refCount;
    value = new StringValue(value->data);
  }
  value->shareable = false;           // add this
  return value->data[index];
}


引用计数的结构:

  • template<class T>                       // template class for smart
    class RCPtr {                           // pointers-to-T objects; T
    public:                                 // must inherit from RCObject
      RCPtr(T* realPtr = 0);
      RCPtr(const RCPtr& rhs);
      ~RCPtr();
    
      RCPtr& operator=(const RCPtr& rhs);
    
      T* operator->() const;
      T& operator*() const;
    
    private:
      T *pointee;
    
      void init();
    };
    
    
    class RCObject {                       // base class for reference-
    public:                                // counted objects
      void addReference();
      void removeReference();
    
      void markUnshareable();
      bool isShareable() const;
    
      bool isShared() const;
    
    protected:
      RCObject();
      RCObject(const RCObject& rhs);
      RCObject& operator=(const RCObject& rhs);
      virtual ~RCObject() = 0;
    
    private:
      int refCount;
      bool shareable;
    };
    
    class String {                           // class to be used by
    public:                                  // application developers
    
      String(const char *value = "");
    
      const char& operator[](int index) const;
      char& operator[](int index);
    
    private:
      // class representing string values
      struct StringValue: public RCObject {
        char *data;
    
        StringValue(const char *initValue);
        StringValue(const StringValue& rhs);
        void init(const char *initValue);
        ~StringValue();
      };
    
      RCPtr<StringValue> value;
    };
    

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值