C++深浅拷贝

深浅拷贝

class String
{
public:
    String(const char *pStr = "")
    {
        if (pStr == NULL)
        pStr = "";
        _str = new char[strlen(pStr) + 1];
        strcpy(_str, pStr);
    }

    ~String()
    {
        if (_str)
            delete[] _str;
    }
private:
    char *_str;
};

int main()
{
    String str1("hello");
    String str2(NULL);
    String str3;

    system("pause");
    return 0;
}

浅拷贝:

也称位拷贝,编译器只是将对象中的值采用基本类型值复制的方式拷贝过来,如果对象中管理资源,最后就会导致多个对象共享同一份资源,当一个对象销毁时就会将该资源释放掉,而此时另一些对象不知道该资源已经被释放, 以为还有效,所以当继续对资源进行操作时,就会发生访问违规

当没有定义copy构造和copy assignment操作符将使用系统默认的copy构造和copy assignment操作符

    String(const String& s)
        :_str(s._str)
    {}

    String &operator=(const String& s)
    {
        _str = s._str;
        return *this;
    }

当类里面有指针对象时,拷贝构造和赋值运算符重载只进行值拷贝,两个对象共用同一块空间,对象销毁时程序会发生内存访问违规

void Test()
{
    String s1("hello");
    
    String s2(s1);

    String s3("world");

    s1 = s3;
}

深拷贝

解决方法:用户给出自己的copy构造和copy assignment操作符

    String(const String& s)
        :_str(new char[strlen(s._str) + 1])
    {
        strcpy(_str, s._str);
    }

    String &operator=(const String& s)
    {
        //不允许自己给自己赋值
        if (this != &s)
        {
            delete[] _str;
            _str = new char[strlen(s._str) + 1];
            strcpy(_str, s._str);
        }
        return *this;
    }

现代写法

    //第一种写法,借助构造函数 
    String(const String& s)
        :_str(NULL)//必须要注意初始化为空
    {
        String tmpstr(s._str);
        swap(_str, tmpstr._str);
    }
    //第一种写法,借助构造函数 
    String &operator=(const String& s)
    {
        if (this != &s)
        {
            String tmpstr(s._str);
            swap(_str, tmpstr._str);
        }
        return *this;
    }

    //第二种写法:借助拷贝构造函数
    //必然会进行对象值拷贝操作(地址会变)
    String &operator = (String s)//s已经是形参的临时变量
    {
        swap(_str, s._str);
        return *this;
    }
posted @ 2019-11-05 22:51  7osen  阅读(272)  评论(0)    收藏  举报