关闭

string类的写时拷贝与引用计数

标签: string引用计数写时拷贝
219人阅读 评论(1) 收藏 举报
分类:
由于浅拷贝使多个对象共用一块内存地址,调用析构函数时导致一块内存被多次释放,导致程序奔溃。
实现string类的时候通常显示的定义拷贝构造函数和运算符重载函数。

由于释放内存空间,开辟内存空间时花费时间,因此,在我们在不需要写,只是读的时候就可以不用新开辟内存空间,就用浅拷贝的方式创建对象,当我们需要写的时候才去新开辟内存空间。这种方法就是写时拷贝。在构造函数中开辟新的空间时多开辟4个字节的空间,用来存放引用计数器,记录这快空间的引用次数。


#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

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:31852次
    • 积分:560
    • 等级:
    • 排名:千里之外
    • 原创:30篇
    • 转载:15篇
    • 译文:0篇
    • 评论:4条
    文章分类
    最新评论