传值/引用是否分别等同于制作深/浅副本?

时间:2017-07-12 19:08:22

标签: pass-by-reference deep-copy pass-by-value equivalent shallow-copy

如果有人以不同方式将其输入搜索栏,请重新提问: pass-by-value与制作深层副本相同,并且通过引用传递与制作浅层副本相同?

如果没有,有什么区别?在Python中,我最熟悉的语言,它们似乎无法区分。

4 个答案:

答案 0 :(得分:5)

没有。这两件事完全没有关系。

浅拷贝/深拷贝正在谈论对象复制;而值传递/传递引用正在讨论传递变量

在许多现代语言中,如Python(你提到过你最熟悉的)和Java,“对象”不是语言中的值,因此不能分配或传递“对象”。相反,对象总是通过指向对象(引用)的指针来操纵,对象是值,可以分配或传递。

Python和Java只是按值传递。传递引用时,它会复制指针,最后会有两个指向同一对象的指针。没有对象复制发生。在这些语言中,对象复制不是通过赋值或传递完成的,而是通过调用.clone()之类的特殊方法或通过将对象传递给构造函数来构造新对象来完成的。 (事实上​​,没有通用的方法来复制Java中的对象。)

有些语言,比如C ++,其中对象可以是值(当然,您也可以使用指向对象的指针,其工作方式与其他语言中的引用类似)。 C还具有传值和传递参考。如果通过引用传递对象,则不会进行复制。如果按值分配或传递对象,则复制该对象。但默认情况下,这是一个浅层副本。

浅拷贝和深拷贝之间的区别在于它们如何处理指向另一个对象的对象成员。不是指针的成员只是被复制;没有“浅”或“深”的概念。 “浅”或“深”只讨论指针的成员 - 是否复制指向的对象。 C ++中的默认赋值运算符和复制构造函数只是复制每个成员。对于作为指针的成员,这意味着指针被复制,因此您有两个指向同一对象的指针。这是一个浅薄的副本。

如果作为指向另一个对象的指针的成员实际上指向的是实际上是“对象的一部分”的“子对象”(无论是指向另一个对象的指针),您可能需要“深度”复制表示子对象是否取决于对象的设计),因此您不希望多个对象指向同一个子对象,这就是您在复制主对象时要复制子对象的原因。要在C ++中实现它,您需要实现自定义赋值运算符和自定义复制构造函数来复制复制过程中的“子对象”。在其他语言中,您同样需要自定义使用的任何复制方法。

答案 1 :(得分:0)

无论如何我都在这里....

浅复制和深复制之间的区别仅与复合对象(包含其他对象的对象,如列表或类实例)有关:

浅表副本会构造一个新的复合对象,然后(在可能的范围内)将对原始对象中的对象的引用插入其中。

深层副本会构造一个新的复合对象,然后递归地将原始对象中的对象的副本插入其中。

有关如何复制对象的信息。当然其中包含对其他对象的引用。

您只是复制直接对象(复制),还是递归复制它也包含引用的所有对象(深复制)。

答案 2 :(得分:0)

传递值对对象进行浅表复制。在矢量情况下;它可以进行深复制。

另一方面,

按引用传递不进行任何复制,它仅通过重命名即可获取对象本身的引用,因此无需任何复制操作。

答案 3 :(得分:-1)

是的,按值传递会生成深层副本,并且按引用传递会生成浅层副本