鱼C论坛

 找回密码
 立即注册
查看: 882|回复: 0

[技术交流] c++深浅拷贝之谜

[复制链接]
发表于 2023-8-4 18:35:35 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
在C++中,深拷贝(Deep Copy)和浅拷贝(Shallow Copy)是两种不同的对象拷贝方式。

浅拷贝是指将一个对象的值复制到另一个对象,包括对象中的数据成员。这样,原始对象和副本对象将共享相同的内存地址。当一个对象被修改时,另一个对象也会受到影响。这可能导致意外的行为和错误。

深拷贝是指完全复制一个对象,包括对象中的数据成员和指向动态分配内存的指针。深拷贝会创建一个新的对象,并为其分配独立的内存空间。这意味着修改一个对象不会影响另一个对象,它们之间是相互独立的。

为了实现深拷贝,通常需要自定义拷贝构造函数和赋值运算符重载函数,来确保所有的数据成员都得到适当地复制,包括动态分配内存的指针。

注意:

浅拷贝只复制对象的值,副本和原始对象共享内存地址,修改一个对象会影响另一个对象。
深拷贝完全复制对象,包括动态分配内存的指针,副本和原始对象是相互独立的,修改一个对象不会影响另一个对象。
选择深拷贝还是浅拷贝取决于具体的需求和对象的结构。对于包含动态分配内存的指针或资源管理的对象,通常需要使用深拷贝来确保数据的独立性和正确性。

例子:

#include <iostream>

class Array {
private:
    int size;
    int* data;

public:
    Array(int s) : size(s), data(new int[size]) {
        for (int i = 0; i < size; i++) {
            data[i] = i;
        }
    }

    // 拷贝构造函数
    Array(const Array& other) : size(other.size), data(new int[other.size]) {
        for (int i = 0; i < size; i++) {
            data[i] = other.data[i];
        }
    }

    // 赋值运算符重载
    Array& operator=(const Array& other) {
        if (this == &other) {
            return *this;
        }

        delete[] data;
        size = other.size;
        data = new int[size];
        for (int i = 0; i < size; i++) {
            data[i] = other.data[i];
        }

        return *this;
    }

    ~Array() {
        delete[] data;
    }

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

int main() {
    Array arr1(5);
    Array arr2 = arr1; // 浅拷贝
    arr1.print(); // 输出:0 1 2 3 4
    arr2.print(); // 输出:0 1 2 3 4

    arr1.print(); // 输出:0 1 2 3 4
    arr2.print(); // 输出:0 1 2 3 4

    // 修改 arr2 的第一个元素
    arr2[0] = 10;

    arr1.print(); // 输出:0 1 2 3 4
    arr2.print(); // 输出:10 1 2 3 4

    return 0;
}
在上面的例子中,我们定义了一个 Array 类来表示动态分配内存的数组。它包含一个指向动态分配内存的指针 data 和一个表示数组大小的变量 size。

在拷贝构造函数和赋值运算符重载函数中,我们实现了深拷贝。它们都会创建一个新的数组,并将原始数组的元素复制到新数组中。这样,每个对象都有自己独立的内存空间,修改其中一个对象不会影响另一个对象。

在 main 函数中,我们创建了两个数组 arr1 和 arr2,并使用 arr1 对象进行初始化 arr2,这是浅拷贝的方式。当我们修改 arr2 中的第一个元素时,arr1 中的对应元素也会被修改,这说明它们共享相同的内存地址。

为了避免这种问题,我们需要实现深拷贝,确保每个对象都有自己独立的内存空间,从而实现数据的独立性和正确性。

评分

参与人数 1荣誉 +5 贡献 +3 收起 理由
歌者文明清理员 + 5 + 3 zc

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-11-16 09:27

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表