Существует (как минимум) два вида клонирования. Большинство ссылок говорят о мелком и глубоком клонировании, но в действительности между ними есть оттенки.
Ключевая проблема заключается в противоречии между тем, «сколько нужно скопировать» и «сколько нужно разделить».
Рассмотрим объект Order
, содержащий ссылки на Customer
, Address
и List
из OrderLines
.
Если вы хотели Clone()
и Order
, в чем дело?
" Простое копирование блока памяти " даст вам новый Order
, но тот, который разделяет Customer
, Address
и тот же List
из OrderLines
. (Помните, что члены объекта хранятся по ссылке, поэтому при дублировании блока памяти вы получите две ссылки на один и тот же объект).
Очевидно, вы не хотите делить List
из OrderLines
между двумя Order
с. На самом деле, вы, вероятно, также хотите клонировать каждый OrderLine
.
Если бы вы работали с методом общего назначения Clone()
, как этот метод мог бы узнать, какие члены должны быть рекурсивно клонированы, а какие нет?
Вообще говоря, это неразрешимая проблема, поэтому отдельные объекты должны реализовать соответствующую семантику для их ситуации .
Последнее замечание: даже когда я создаю возможность для Clone()
объектов, я не склонен создавать Clone()
метод, вместо этого я предпочитаю конструктор копирования - конструктор, который принимает другой объект как основа. Если вы не можете найти Clone()
, поищите это.