从string类谈C++深浅拷贝的区别和意义

来源:互联网 发布:java接收微信事件推送 编辑:程序博客网 时间:2024/05/17 07:44

浅拷贝和深拷贝
深浅拷贝是在C++编程中,对于类对象来说,其内部存在各种类型成员变量,在拷贝过程中会出现问题。
浅拷贝在有指针的情况下,浅拷贝只是增加了一个指针指向已经存在的内存,而深拷贝就是增加一个指针并且申请一个新的内存,使这个增加的指针指向这个新的内存

char* _ptr;int _countRef;

_countRef 对这块空间进行监视,当一直有指针指向这块空间时不对它进行释放,当引用计数为0时再对其释放,这样就避免了刚刚出现的问题,具体代码如下:

#include <iostream>using namespace std;class String{public:    String(const char* ptr = "")        :_countRef(new int(1))    {        if (ptr == NULL)        {            _ptr = new char;            *_ptr = '\0';        }        else        {            _ptr = new char[strlen(ptr) + 1];            strcpy(_ptr, ptr);        }        *_countRef = 1;    }    String(const String & s)        :_ptr(s._ptr)        , _countRef(s._countRef)    {        ++(*_countRef);    }    ~String()    {        Release();    }    void Release()    {        if (--(*_countRef) == 0)        {            delete[] _ptr;            _ptr = NULL;            delete _countRef;        }    }    String& operator= (const String & s)    {        if (_ptr != s._ptr)        {            Release();//对被赋值的对象进行检查,并释放它自己的指针            _ptr = s._ptr;            _countRef = s._countRef;            ++(*_countRef);        }        return *this;    }private:    char* _ptr;    int* _countRef;};

写时拷贝由于释放内存空间,开辟内存空间时花费时间,因此,在我们在不需要写,只是读的时候就可以不用新开辟内存空间,就用浅拷贝的方式创建对象,当我们需要写的时候才去新开辟内存空间。这种方法就是写时拷贝。在原有的引用计数的基础上加上写时拷贝:

char operator[](int index)    {        if ((*_countRef) > 1)//当引用计数大于1时开辟新空间        {            --(*_countRef);            _countRef = new int(1);            char* ptr = new char[strlen(_ptr) + 1];            strcpy(ptr, _ptr);            _ptr = ptr;//让指针指向新开辟的空间        }        return _ptr[index];         }

深拷贝是开辟一块新的空间,让新空间中的内容和原空间内容完全相同,然后让指针指向这块空间,这样在析构时不会造成对同一块内存空间释放多次的情况

 #include <iostream>  #include <string>class String{public:     String(const char* pStr="")    {         if (pStr == NULL)         {             _pStr = new char;             *_pStr = '\0';         }         else         {             _pStr = new char[strlen(pStr) + 1];             strcpy(_pStr, pStr);         }    }     String(const String &s)         :_pStr (_pStr = new char[strlen(s._pStr) + 1])     {         strcpy(_pStr, s._pStr);     }     String &operator=(const String &s)     {         if (this != &s)         {             char *pTemp = new char[strlen(s._pStr) + 1];             strcpy(pTemp, s._pStr);             delete[] _pStr;             _pStr = pTemp;         }         return * this ;     }     ~String()  //析构函数     {         if (_pStr)         {             delete[] _pStr;             _pStr = NULL;         }     }private:    char* _pStr;};void FunTest(){    String s1="1234";    String s2;    s2 = s1;    String s3(s2);    String s4 = "asahsg";}int main(){    FunTest();    system("pause");    return 0;}

合理选用合适的拷贝有利于提高代码的效率。

0 0
原创粉丝点击