浅析浅拷贝与深拷贝

标签: string  对象  内存  class

一、浅拷贝:
浅拷贝就是成员数据之间的赋值,把值赋给要拷贝的。即在对象复制时,只是对对象中的数据成员进行简单的赋值,所以会导致多个对象共用一块内存空间,当一个对象将这块内存释放掉之后,另外对象并不知道空间已经还给了系统,所以会在对这段内存空间进行访问时出现访问违规。
如下例子:

class String
{
public:
    String(const char*str = "") //构造函数
    {
     if (NULL == str)
     {
        _str = new char[1];
        *_str = '\0';
    }
    else
        _str = new char[strlen(str) + 1];
        strcpy(_str, str);
    }
    String(const String&d)   //浅拷贝
        :_str(d._str)
    {}
    String&operator=(const String&d)      //赋值运算符
    {
        if (this != &d)
        {
            _str = d._str;
        }
        return *this;
    }
private:
    char*_str;
};
int main()
{
    String c1="hello";
    String c2(c1);
    cout << c2 << endl;
    system("pause");
    return 0;
}

这里写图片描述
二、深拷贝
在深拷贝的情况下,要进行重新动态分配空间,进行动态内存开辟。具体的String实现如下:

class String
{
public:
    String(const char*str = "") //构造函数
    {
     if (NULL == str)
     {
        _str = new char[1];
        *_str = '\0';
    }
    else
        _str = new char[strlen(str) + 1];
        strcpy(_str, str);
    }
    String(const String &d) //拷贝构造函数(深拷贝)
    {
        _str=new char[strlen(d._str) + 1];
        strcpy(_str, d._str);

    String &operator=(const String &d)   //赋值运算符
    {
        if (this != &d)
        {
            char*pstr = new char[strlen(d._str) + 1];
            strcpy(pstr, d._str);
            delete[]_str;
            _str = pstr;
        }
        return *this;
    }
    bool operator==(const String&d)const
    {
        if (strlen(_str) != strlen(d._str))
        {
            return false;
        }
        if ((strcmp(_str, d._str)) == 0)
            return true;
        else
            return false;           
    }
    bool operator<(const String&d)const
    {
        if (strcmp(_str, d._str) < 0)
        {
            return true;
        }
        return false;
    }
    bool operator>(const String&d)const
    {
        if (strcmp(_str, d._str)>0)
        {
            return true;
        }
        return false;
    }
    bool operator<=(const String&d)const
    {
        if (strcmp(_str, d._str) <=0)
        {
            return true;
        }
        return false;
    }
    bool operator>=(const String&d)const
    {
        if (strcmp(_str, d._str)>=0)
        {
            return true;
        }
        return false;
    }   
    char operator[](int idx) // 数组索引
    {
        if (idx > 0 && (idx < strlen(_str)))
            return _str[idx];
    }
    size_t size()
    {
        return strlen(_str); 
    }
    ~String()
    {
        delete[] _str;
    }
    friend ostream&operator<<(ostream&_cout, String&d);
    friend istream&operator>>(istream&_cin, String&d);
private:
    char*_str;
};
ostream &operator<<(ostream&cout, String&d)
{
    cout << d._str;
    return cout;
}
istream&operator>>(istream&cin, String&d)
{
    char str[20];
    cin >> str;
    d = str;
    return cin;
}
int main()
{
    String c1="hello";
    cout << c1 << endl;
    String c2 = "world";
    cout << boolalpha <<(c1 ==c2)<<endl ;
    String c3(c2);
    cout << c3 << endl;
    cout << c3[2] << endl;
    system("pause");
    return 0;
}

具体运行结果如下:
这里写图片描述
以上是深拷贝的普通版。
下面示例为深拷贝的简洁版:

只需将拷贝构造与赋值运算符重载修改即可:
String(const String &d) //拷贝构造函数(深拷贝)
    {
        String temp(d._str);
        swap(_str, temp._str);
    }

    String &operator=(const String &d)   //赋值运算符
    {
        if (this != &d)
        {
            String temp(d._str); //调用构造函数
            swap(_str, temp._str);
        }
        return *this;
    }

此时,在完成对象的复制后,内存的一个大致情况如下:

此时c1和c2各自指向一段内存空间,但它们指向的空间具有相同的内容,这就是所谓的“深拷贝”。

版权声明:本文为xiaodu655原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/xiaodu655/article/details/78148833