首页 > 代码库 > 深拷贝&浅拷贝&引用计数&写时拷贝

深拷贝&浅拷贝&引用计数&写时拷贝

(1).浅拷贝:

class String
{
public:
     String(const char* str="")
          :_str(new char[strlen(str)+1])
     {
          strcpy(_str,str);
     }
     ~String()
     {
          if(NULL!=_str)
          {
              delete[] _str;
              _str=NULL;
          }
     }
private:
     char* _str;
};
int main()
{
     String s1("hello");
     String s2(s1);
     String s3=s2;
     return 0;
}
技术分享
***s1、s2、s3共用一块存储空间
***在浅拷贝中,由于拷贝构造函数和复制运算符重载时,只把已有对象的内容赋给新创建的对象,导致多个对象公用了同一段内存,结果当任意一个对象销毁时他就会释放那段他们公用的内存,当剩下的对象在被销毁时,就回重复的释放那段内存空间,导致程序崩溃
 

      (2).深拷贝:

String(const String& s)
    {
        _str = new char[strlen(s._str) + 1];
        strcpy(_str, s._str);
    }
    String& operator= (String &s)
    {
        if (this != &s)
        {
            String tmp(s);
            swap(_str, s._str);
        }
        return *this;
    }
自己实现拷贝构造函数和赋值操作符的重载,对于不同的对象,给他们开辟出不同的内存用于存放字符串

     (3).引用计数

class String
{
public:
    String(const char *str = "")
        :_str(new char[strlen(str) + 1])
          ,_count (new int[1])
    {
        strcpy(_str, str);
          *_count=1;
    }
    String(const String& s)
    {
        _str=s._str;
          _count=s._count;
          (*_count)++;
    }
    ~String()
    {
          if(NULL!=_str && (*_count)==1)
          {
              delete[] _str;
              _str = NULL;
          }
          else if((*_count)>1)
          {
              (*_count)--;
          }
    }
private:
    char *_str;
     int* _count;
};

int main()
{
    String s1("hello");
    String s2(s1);
    String s3 = s2;
    return 0;
}
***引用计数,它是多个对象一同进行维护的。比如创建s1之后,s1的引用计数就为1,通过s1创建s2,s1和s2共用了s1的字符串。则s1和s2的引用计数要一致为2。为了实现,所以在成员变量定义一个int* 类型的指针,这个指针指向存储引用计数的空间,多个对象指向同一块的引用计数空间时,说明他们使用的同一字符串
***引用计数存在一个很重要的缺点,就是当多个对象使用同一个字符串时,任何一个对象修改字符串里面的值都会造成其他对象所指向的字符串改变!

(4).写时拷贝:多个对象共用共用一个内存空间的内容,哪个对象想修改内容,这个时候把内容拷贝一份给这个对象,免除对象修改内容影响其他对象

 

深拷贝&浅拷贝&引用计数&写时拷贝