[C++] 浅拷贝和深拷贝

浅拷贝只是简单的值拷贝;

深拷贝需要重新分配空间。

 

系统默认的拷贝构造函数属于浅拷贝。

#include <iostream>

using namespace std;

class A {
public:
    char *p;

    A(char *a) {
        int len = strlen(a) + 1;
        p = new char[len];
        memcpy(p, a, len);
    }

    void print(void) {
        cout << p << endl;
    }
};

int main(void) {
    A m("Hello");
    m.print();

    // 使用系统默认的拷贝构造函数
    A n(m);
    n.print();

    // 修改对象m的成员变量,对象n的也随之改变
    strcpy(m.p, "World");
    m.print();
    n.print();
}

输出结果为:

Hello
Hello
World
World

 

为什么修改对象 m 的值,对象 n 的值也随之改变?

原因是在创建对象 m 时,构造函数中为其分配了所需要的内存空间,对象 m 的成员变量指针 p 会指向分配内存空间的首地址;

当使用默认的拷贝构造函数,利用对象 m 初始化对象 n 时,只是简单的将对象 n 的成员变量指针 p 也指向对象 m 分配的内存空间的首地址;

两个指针指向同一个内存空间,当其中任意一个对象修改了内存空间中的值,另一个也随之改变。

 

浅拷贝的影响:

如果在类的析构函数中 delete 内存,那么同一块内存会被销毁两次,这样会导致系统错误。

 

如果想要在修改其中一个对象时而不影响另一个对象,就要使用深拷贝,也就是自定义拷贝构造函数,在拷贝构造函数中为新对象重新分配内存空间。

 

#include <iostream>

using namespace std;

class A {
public:
    char *p;

    A(char *a) {
        int len = strlen(a) + 1;
        p = new char[len];
        memcpy(p, a, len);
    }

    // 自定义拷贝构造函数,深拷贝
    A(const A &a) {
        int len = strlen(a.p) + 1;
        // 重新分配内存空间
        p = new char[len];
        memcpy(p, a.p, len);
    }

    void print(void) {
        cout << p << endl;
    }
};

int main(void) {
    A m("Hello");
    m.print();

    // 使用自定义的拷贝构造函数
    A n(m);
    n.print();

    // 修改对象m的成员变量,对象n的不会改变
    strcpy(m.p, "World");
    m.print();
    n.print();
}

输出结果为:

Hello
Hello
World
Hello

posted @ 2019-12-22 18:13  LeeAaron  阅读(408)  评论(0编辑  收藏  举报