pass-by-value/reference 是否等同于制作 deep/shallow 副本?

Is pass-by-value/reference equivalent to making a deep/shallow copy, respectively?

为了防止有人以不同方式在搜索栏中键入问题,请改写问题: 值传递和深拷贝一样吗,引用传递和浅拷贝一样吗?

如果不是,有什么区别?在我最熟悉的Python语言中,它们看起来难以区分。

是的,按值传递进行深拷贝而按引用传递进行浅拷贝

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

浅copy/deep拷贝是说对象拷贝;而 pass-by-value/pass-by-reference 是在谈论 传递变量

在许多现代语言中,像 Python(您提到的您最熟悉的)和 Java、"objects" 不是语言中的值,因此 "objects" 不能赋值或传递。相反,对象总是通过指向对象(引用)的指针来操作,这些指针是值并且可以被分配或传递。

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

有一些语言,例如 C++,其中对象可以是值(当然,您也可以有指向对象的指针,这与其他语言中的引用类似)。 C 还具有按值传递和按引用传递。如果通过引用传递对象,则不会发生复制。如果按值分配或传递对象,则会复制该对象。但默认情况下这是一个浅拷贝。

浅拷贝和深拷贝的区别在于它们如何处理作为指向另一个对象的指针的对象成员。不是指针的成员只是简单地复制;没有 "shallow" 或 "deep" 的概念。 "Shallow" 或 "deep" 只讨论作为指针的成员——是否复制指向的对象。 C++ 中的默认赋值运算符和复制构造函数只是复制每个成员。对于指针成员,这意味着指针被复制,因此您有两个指向同一对象的指针。那就是浅拷贝。

您可能需要一个 "deep" 副本,以防作为指向另一个对象的指针的成员实际上指向一个 "sub-object" ,而该 "sub-object" 实际上是 "a part of" 您的对象(无论是指向另一个对象的指针是否表示子对象取决于对象的设计),因此您不希望多个对象指向同一个子对象,这就是为什么要复制子对象的原因复制主要对象。要在 C++ 中实现这一点,您需要实现自定义赋值运算符和自定义复制构造函数以在复制过程中复制 "sub-objects"。在其他语言中,您同样需要自定义使用的任何复制方法。

无论如何我都在这里..来自文档...

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

浅拷贝构造一个新的复合对象,然后(在可能的范围内)向其中插入对在原始对象中找到的对象的引用。

深拷贝构造一个新的复合对象,然后递归地将在原始对象中找到的对象的副本插入其中。

所以它是关于如何复制一个对象..当然包含对其他对象的引用。

你是只复制直接对象(copy),还是递归复制它持有引用的所有对象(deepcopy)。

按值传递 生成对象的浅拷贝。

另一边,

pass-by-reference不做任何复制,它只是通过重命名获取对象本身的引用,所以没有任何复制操作。