拷贝构造之“深拷贝”和“浅拷贝”

深拷贝和浅拷贝是对象复制中的两个重要概念,特别是在处理动态内存分配时,这两个概念尤为重要。

一、浅拷贝(Shallow Copy)

浅拷贝是对象复制的一种方式,它只复制对象的所有成员变量的值。如果对象包含指针或动态分配的内存,浅拷贝只复制指针的值(即地址),而不复制指针所指向的实际内容。这意味着两个对象共享同一块内存区域,修改其中一个对象的数据会影响另一个对象。

#include <iostream>
using namespace std;

class Shallow {
public:
    Shallow(int size) : size(size) {
        data = new int[size]; // 动态分配内存
        for (int i = 0; i < size; ++i) {
            data[i] = i;
        }
    }

    // 拷贝构造函数:执行浅拷贝(使用成员初始化列表)
    Shallow(const Shallow& source) : size(source.size), data(source.data) {
        cout << "Shallow Copy Constructor Called" << endl;
    }

    //析构函数释放开辟的动态空间
    // ~Shallow() {
    //     delete[] data; // 释放内存
    //     cout << "Destructor Called" << endl;
    // }

    void display() const {
        for (int i = 0; i < size; ++i) {
            cout << data[i] << " ";
        }
        cout << endl;
    }

    void setDate(){
        this->data[0] = 9;
    }

private:
    int* data;
    int size;
};

int main() {
    Shallow obj1(5);
    Shallow obj2 = obj1; // 调用浅拷贝构造函数

    obj1.display();
    obj2.display();

    cout << "对obj进行数据更改" << endl;
    obj2.setDate();

    obj1.display();
    obj2.display();
}

在这个例子中,obj2 是通过浅拷贝构造函数从 obj1 创建的,因此 obj1 和 obj2 共享同一块内存。修改一个对象的数据会影响另一个对象。

在这里插入图片描述

二、深拷贝(Deep Copy)

深拷贝是对象复制的另一种方式,它不仅复制对象的所有成员变量的值,还会为指针或动态分配的内存分配新的内存空间,并复制指针所指向的实际内容。这意味着两个对象拥有独立的内存区域,修改其中一个对象的数据不会影响另一个对象。

#include <iostream>
using namespace std;

class Deep {
public:
    Deep(int size) : size(size) {
        data = new int[size]; // 动态分配内存
        for (int i = 0; i < size; ++i) {
            data[i] = i;
        }
    }

    // 拷贝构造函数:执行深拷贝
    Deep(const Deep& source) : size(source.size) {
        data = new int[source.size];
        for (int i = 0; i < size; ++i) {
            data[i] = source.data[i];
        }
        cout << "Deep Copy Constructor Called" << endl;
    }

    ~Deep() {
        delete[] data; // 释放内存
        cout << "Destructor Called" << endl;
    }

    void display() const {
        for (int i = 0; i < size; ++i) {
            cout << data[i] << " ";
        }
        cout << endl;
    }

    void setDate(){
        this->data[0] = 9;
    }

private:
    int* data;
    int size;
};


int main() {
    Deep obj1(5);
    Deep obj2 = obj1; // 调用浅拷贝构造函数

    obj1.display();
    obj2.display();

    cout << "对obj进行数据更改" << endl;
    obj2.setDate();

    obj1.display();
    obj2.display();
}

在这个例子中,obj2 是通过深拷贝构造函数从 obj1 创建的,因此 obj1 和 obj2 拥有独立的内存。修改一个对象的数据不会影响另一个对象。

在这里插入图片描述

三、深拷贝和浅拷贝的比较

  1. 浅拷贝:
    只复制指针的值(地址),不复制指针所指向的实际内容。
    对象共享同一块内存,修改一个对象的数据会影响另一个对象。
    更快但风险更高,特别是在对象生命周期不同步的情况下。
  2. 深拷贝:
    复制指针所指向的实际内容,分配新的内存空间。
    对象拥有独立的内存,修改一个对象的数据不会影响另一个对象。
    比浅拷贝更安全,但需要更多的时间和内存。

何时使用深拷贝和浅拷贝

  • 浅拷贝适用于对象之间不共享动态内存的情况,或当你确定对象的生命周期是同步的。
  • 深拷贝适用于对象之间需要独立管理动态内存的情况,避免共享内存带来的潜在问题。

四、其他注意事项

  1. 是实行浅拷贝时,因为对象之间共享动态内存,因此注意在执行析构函数时,造成一块动态内存的两次释放,造成程序错误。如浅拷贝部分代码的析构函数如果不注释就会造成空间的重复释放。
  2. 对于列表成员初始化不熟悉的可以看这篇文章:列表成员初始化
  • 12
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值