0
点赞
收藏
分享

微信扫一扫

C++——深拷贝与浅拷贝

AbrahamW 2022-01-22 阅读 67

好久之前学的了,在CLion上试一下,发现为什么用的浅拷贝还是可以正常运行,于是转到了CB,发现还是可以正常运行,最后用了VS2022,就不行。

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <cstring>
//默认复制函数带来的问题

using namespace std;

class String
{
public:
    char* str;
    int len;
public:
    String(const char* s)
    {
        len = strlen(s);
        str = new char[len + 1];
        strcpy(str,s);
    }
    String(String& s)
    {
        len = s.len;
        str = new char[len + 1];    //深拷贝,在堆区创建副本,delete的时候释放的是这个堆区的副本,不会影响原本
        strcpy(str, s.str);
        cout << "拷贝构造函数的调用" << endl;
    }
    ~String()
    {
        cout << "析构函数的调用" << endl;
        delete[]str;
    }
};

void usevalue(String s)
{
    cout << s.str << endl;
}
int main()
{
    String s = "hello world";
    cout << s.str << endl;
    usevalue(s);
    cout << s.str << endl;
    return 0;
}

浅拷贝就是临时的副本复制的是直接复制原本,delete的时候影响了原本,因为浅拷贝是直接复制,副本中的指针和原本中的指针指向的是同一块地方,做深拷贝改进。

另外在进行类的复制运算时要想清怎样设计这个类,例如

String a,b;
a = "hello world";
b = a;

这样我们感觉是没有问题的,但其实他是有点问题的,同样是浅拷贝造成的安全隐患,a与b中的指针指向的是同一块地方,我们可能在对b操作的时候误操作到了a,这也需要设计一个 重载= 来进行深拷贝赋值。

最明显的一个错误:当程序结束时,会重复释放a,b指向的内存造成错误

String & operator=(const String &s)
{
    if(this.str == s.str)
        return this;
    delete [] str;
    len = s.len;
    str = new char[len + 1];
    strcpy(str,s.str);
    return *this;
}

同样,这就需要我们也对默认构造函数改进以下,这里就不陈述了。 

先释放原有的内容,再进行新串的赋值,返回引用是为了链式链接,即可以连等

String a,b,c;
a = "C++";
c = b = a; //if return reference OK
举报

相关推荐

0 条评论