克隆对象是什么意思?

8

什么是VB6或Java中的对象克隆?我们在什么情况下使用克隆?克隆对象是什么意思?请举个例子说明。


1
对于有经验的人来说,这似乎很明显,但初学者常常会遇到“嘿,为什么我改变了这个‘其他’对象后我的对象也改变了”的困惑。意识到名称基本上是装饰过的指针需要一定的时间(理解克隆可以大大加快这个过程)。 - Brian Knoblauch
2个回答

10

克隆实际上是将对象数据复制到一个新的对象中。

这个例子并没有克隆数据:

Foo p = new Foo();
Foo o = p;

如果Foo有一个成员a,并且您更改了p.a,那么o.a也会更改,因为po都指向同一对象。

然而,

Foo p = new Foo();
Foo o = p.Clone();

如果你改变p.a,那么o.a不会改变,因为它们实际上指向不同的对象。

事实上,有两种不同的克隆方式:浅克隆和深克隆。

浅克隆只是创建一个新的对象并将成员复制到新对象中。这意味着如果其中一个成员实际上是指向另一个对象的指针,则该对象将在旧对象和新对象之间共享。

深克隆实际上会遍历并将所有成员克隆到新对象中。这样对象就是所有数据的完整副本。


顺便提一下,还有第三种克隆方式——语义级别的克隆。例如,List<T> 的语义级别克隆将是一个包含与旧列表相同项的新列表。 - supercat
@supercat - 这与列表的浅克隆有何不同? - Aaron
@Aaron:假设一个集合被实现为对数组的引用以及有效项的计数。持有这样一个集合的对象的浅克隆将是一个新对象,它具有复制的有效项计数,但是与原始对象相同的项目数组的引用。语义级别的克隆将具有复制的计数和对数组的浅克隆的引用。 - supercat
@Aaron:制作对象的语义级克隆的好方法是从浅层克隆开始,然后克隆对象“知道”的所有字段。对象通常不应公开浅克隆功能,而只在内部使用它。 - supercat
@supercat - 我明白了 - 语义级别的克隆就像是浅克隆,它知道复杂对象的内部结构。很好知道这一点。 - Aaron
@Aaron:这是一个有用的概念,我没有看到过讨论。在许多情况下,这是“克隆”方法最合乎逻辑的行为。 - supercat

2

一般来说,对象是通过引用传递的。因此,如果你说 $objB=$objA,你并没有得到一个新的对象;你得到的是一个同一对象的新名称。但是,如果你说 $objB= clone $objA,你就会得到一个 $objA 的副本。在第一种情况下,无论你对 $objB 做什么,都会发生在 $objA 上。而在第二种情况下,$objB 是独立的。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接