快速弄懂C++中的深拷贝和浅拷贝

浅拷贝

浅拷贝就是单纯拷贝指向该对象的内存,所以在进行多次浅拷贝后只是相当于多了几个指向同一个对象的指针,而深拷贝相当于完全复制了一个对象副本。浅拷贝指的是复制对象的所有成员变量的值,不管这些值是指针、基本数据类型还是其他对象,但当涉及到指针时,浅拷贝只会复制指针的值(即地址),而不是它所指向的数据,这可能会导致多个对象共享相同的数据。这与深拷贝相反,深拷贝会创建原对象指针所指向的数据的一个新副本。

默认的拷贝构造函数和赋值运算符实现的就是浅拷贝。因此,如果你不为类提供自定义的拷贝构造函数和赋值运算符,编译器会为你提供默认的实现,这就是浅拷贝。

以下是一个简单的浅拷贝的例子:

#include <iostream>

class ShallowCopy {
public:
    int* data;
    
    ShallowCopy(int d) {
        data = new int(d);
    }
    
    // 使用编译器生成的默认拷贝构造函数
    // ShallowCopy(const ShallowCopy& src) = default;

    // 使用编译器生成的默认赋值运算符
    // ShallowCopy& operator=(const ShallowCopy& src) = default;

    ~ShallowCopy() {
        delete data;
    }
};

int main() {
    ShallowCopy obj1(10);
    ShallowCopy obj2 = obj1; // 这里进行了浅拷贝

    std::cout << *obj1.data << " " << *obj2.data << std::endl; // 输出: 10 10

    *obj1.data = 20;

    std::cout << *obj1.data << " " << *obj2.data << std::endl; // 输出: 20 20

    return 0;
}

在上面的例子中,当obj2是通过obj1的拷贝构造函数创建的时,进行的是浅拷贝,所以obj1.dataobj2.data都指向相同的地址。因此,改变其中一个也会影响到另一个。

注意:浅拷贝通常是不安全的,特别是当类中有动态分配的资源时。在上面的例子中,当obj1obj2都析构时,它们都会尝试释放同一块内存,这会导致未定义的行为。为了避免这种情况,你通常需要实现深拷贝或者使用智能指针来管理资源。

深拷贝

在C++中,深拷贝意味着当对象被拷贝时,不仅复制对象的所有成员变量值,而且还复制其指针成员变量所指向的数据。这与浅拷贝相反,浅拷贝只会复制指针的值而不是其所指向的数据,可能导致多个对象共享相同的数据。

为了实现深拷贝,你通常需要为类提供自定义的拷贝构造函数和赋值运算符,并在其中对指针成员进行深拷贝。

下面是一个深拷贝的示例:

#include <iostream>

class DeepCopy {
private:
    int* data;
    
public:
    DeepCopy(int d) {
        data = new int(d);
    }
    
    // 自定义拷贝构造函数,实现深拷贝
    DeepCopy(const DeepCopy& src) {
        data = new int(*(src.data));
    }
    
    // 自定义赋值运算符,实现深拷贝
    DeepCopy& operator=(const DeepCopy& src) {
        if (this == &src) {
            return *this;  // 处理自赋值的情况
        }
        
        delete data; // 删除当前对象的资源

        // 为当前对象分配新的资源,并拷贝内容
        data = new int(*(src.data));

        return *this;
    }

    ~DeepCopy() {
        delete data;
    }

    // Getter for demonstration purposes
    int getData() const {
        return *data;
    }
};

int main() {
    DeepCopy obj1(10);
    DeepCopy obj2 = obj1; // 使用自定义拷贝构造函数,实现深拷贝

    std::cout << obj1.getData() << " " << obj2.getData() << std::endl; // 输出: 10 10

    // 修改obj2的内容
    DeepCopy obj3(30);
    obj2 = obj3;

    std::cout << obj1.getData() << " " << obj2.getData() << " " << obj3.getData() << std::endl; // 输出: 10 30 30

    return 0;
}

在上面的例子中,深拷贝确保了当一个对象被拷贝或分配时,每个对象都有其自己独立的资源副本,这避免了多个对象共享相同的资源。

  • 10
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值