欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

浅析浅拷贝与深拷贝

程序员文章站 2022-03-10 22:08:26
...

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

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各自指向一段内存空间,但它们指向的空间具有相同的内容,这就是所谓的“深拷贝”。