深拷贝与浅拷贝

深拷贝和浅拷贝是指在计算机编程中,当需要复制一个对象时,复制出来的副本与原对象之间的关系的不同。

浅拷贝是指在复制对象时,只复制了对象本身的值,而没有复制对象包含的子对象。也就是说,新对象只是原对象的一个引用,任何对新对象的修改都会影响到原对象。

浅拷贝

指针成员变量初始化指向堆区空间

析构函数释放堆区空间后指针为野指针,需赋值为NULL

成员变量为指针时,且指向堆区空间时浅拷贝会出错

深拷贝则是指在复制对象时,不仅复制对象本身的值,还复制了对象包含的所有子对象,即新对象与原对象完全独立,对新对象的任何修改都不会影响原对象。通常可以使用copy.deepcopy()函数实现。

在拷贝构造函数中,类中有一个指针变量,如果在堆区开辟指针指向的数据,再进行浅拷贝的话,拷贝后的对象的指针同样指向源对象的堆区数据,在执行析构函数后会进行释放,两个对象均释放会报错!!!

需要注意的是,有些对象可能包含循环引用,即某个对象中包含对自身的引用。这时进行深拷贝可能会导致无限递归,因此在进行深拷贝时需要注意处理循环引用的情况。

深拷贝

深拷贝重新开辟一个值一样的不同区域,则指针也不同,不用担心堆区重复释放

浅拷贝和赋值是两个不同的概念,虽然它们看起来很相似,但在细节上有很大的区别。

赋值也分为值赋值和地址赋值,不涉及地址赋值的话,类似于深拷贝,开辟不同区域;如果涉及地址赋值的话类似与浅拷贝,指向相同区域数据;是将一个对象的引用赋给另一个对象,使得它们指向同一个内存地址,即两个对象共享同一份数据,对其中一个对象的修改也会影响另一个对象。例如:

int main()              //不涉及地址的赋值操作
{
    int a = 10;
    int b = a;
    a = 11;
    cout << "a="<<a << endl;
    cout << "b="<<b << endl;
    return 0;
}
 #输出 a=11 b=10
int main()                //引用,涉及地址赋值
{
    int a = 10;
    int &b = a;
    a = 11;
    cout << "a="<<a << endl;
    cout << "b="<<b << endl;
    return 0;
} #输出 a=11 b=11
list1 = [1, 2, 3]          //数组赋值,涉及地址传递
list2 = list1
list2[0] = 0
print(list1)  # 输出 [0, 2, 3]

浅拷贝是创建一个新的对象,其中包含了原始对象中的一部分数据,例如列表或字典中的元素对象,但这些元素对象本身仍然是原对象的引用。因此,对于元素对象的修改会反映在原对象和浅拷贝对象中。例如:

list1 = [[1, 2], [3, 4]]            //浅拷贝未开辟新的数据区域,只是简单地创建了一个新的变量,但它们指向同一块内存
list2 = list1.copy()
list2[0][0] = 0
print(list1)  # 输出 [[0, 2], [3, 4]]

在这个例子中,list2list1 的浅拷贝,因此它们都指向同样的子列表。因此,修改 list2 中的子列表会影响到 list1 中的子列表。

总的来说,赋值只是简单地创建了一个新的变量,但它们指向同一块内存,因此它们是相互关联的。而浅拷贝则是创建了一个新的对象,但这个对象与原始对象共享某些子对象的引用,因此在修改这些子对象时需要特别小心。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值