写时拷贝

1.写时拷贝的定义:

       由于浅拷贝使多个对象共用一块内存地址,调用析构函数时导致一块内存被多次释放,导致程序奔溃。

       写时拷贝,就是在写的时候(即改变字符串的时候)才会真正开辟空间(深拷贝),如果只对数据读取时,就对数据进行浅拷贝,也称写时拷贝。

       写时拷贝技术是通过“引用计数”实现的,在分配空间的时候多分配4个字节,用来存放引用计数器,记录这块空间的引用次数。当有新的指针指向这块空间时,引用计数加一,当要释放这块空间时,引用计数减一(假装释放),直到引用计数减为0时才真正释放掉这块空间。当有指针要改变这块空间的值时,再为这个指针分配自己的空间(注意这时引用计数的变化,旧空间的引用计数减一,新分配的空间引用计数加一)。



2. string中的两种写时拷贝


#include<iostream>  
#include<stdlib.h>  
using namespace std;  
class String  
{  
public:  
     String(char *str = "")  
      :_str(new char[strlen(str) + 5])  
     {  
          *(int *)_str = 1;  
          _str += 4;  
          strcpy(_str, str);  
     }  
     ~String()  
     {  
          if (_str != NULL)  
          {  
              _Release();  
          }  
     }  
     String(const String& str)  
     {  
          _str = str._str;  
          ++_GetRefCount();  
     }  
     String& operator=(const String& str)  
     {  
          if (this != &str)  
          {  
               _Release();  
               _str = str._str;  
               ++ _GetRefCount();  
          }  
          return *this;  
     }  
     char& operator[](int index)//写时拷贝  
     {  
   
          if (_GetRefCount()>1)//当引用次数大于1时新开辟内存空间  
          {  
               --_GetRefCount();//原来得空间引用计数器减1  
               char *str = new char[strlen(_str) + 5];  
               strcpy(str+4, _str);  
               _str = str+4;  
               _GetRefCount()++;  
          }  
          return _str[index];  
     }  
     friend ostream& operator<<(ostream& output, const String& str)  
     {  
          output << str._str;  
          return output;  
     }  
   
private:  
     int& _GetRefCount()  
     {  
          return *(int *)(_str - 4);  
     }  
     void _Release()  
     {  
          if (--_GetRefCount() == 0)  
          {  
               delete[] (_str-4);  
          }  
     }  
private:  
     char *_str;  
};  




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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值