В чем разница между глубокой и мелкой копиями?

754

В чем разница между глубокой и мелкой копиями?

Дэвид Лок
источник
6
К какой технологии это относится?
Суреш Варма
42
@SureshVarma, это концепция программирования!
Маниш Шривастава

Ответы:

763

Мелкие копии дублируют как можно меньше. Мелкая копия коллекции - это копия структуры коллекции, а не ее элементы. С мелкой копией две коллекции теперь совместно используют отдельные элементы.

Глубокие копии дублируют все. Глубокая копия коллекции - это две коллекции со всеми дублированными элементами оригинальной коллекции.

С. Лотт
источник
Может быть, реализация .NET MemberwiseClone () делает больше, чем поверхностное копирование в обычном смысле
Lu55
5
Имейте в виду, что есть также смешанные копии (не только такие, как ленивые копии ), которые дублируют только часть этого ( вот пример )! ;)
Cregox
Таким образом, мелкая копия X может изменить элементы в X, а глубокая копия не может?
каштановая
1
что такое структура коллекции?
Мед
1
Коллекции @Honey могут представлять собой разнообразные структуры данных, в которых хранятся несколько элементов данных. В python у нас есть кортеж, список, словарь и т. Д.
Murphy
852

Ширина против Глубины; мыслить в терминах дерева ссылок с вашим объектом в качестве корневого узла.

Мелкий:

Перед копированием Мелкое копирование Мелкий Готово

Переменные A и B относятся к разным областям памяти, когда B присваивается A, две переменные относятся к одной и той же области памяти. Более поздние модификации содержимого любого из них немедленно отражаются в содержимом другого, поскольку они разделяют содержимое.

Deep:

Перед копированием Глубокое копирование Глубоко сделано

Переменные A и B относятся к различным областям памяти, когда B присваивается A значения в области памяти, на которые указывает A, копируются в область памяти, на которую указывает B. Более поздние модификации содержимого либо остаются уникальными для A или B; содержание не передается.

dlamblin
источник
33
Вот статья из Википедии, из которой взята эта иллюстрация, если она не имеет смысла вне контекста. En.wikipedia.org/wiki/Object_copy#Shallow_copy
corbin
4
В случае поверхностного копирования, если мы сделаем какие-либо изменения в массиве B, это будет отражено в массиве A, поскольку A и B указывают на одну и ту же область памяти?
tek3
3
В одной строке его копия по ссылке против копии по значению. Не уверен, что ответ правильный!
Манну
2
изображения взяты из Википедии без цитирования
jasonleonhard,
10
@jasonleonhard Итак, 9 лет назад я просто поместил ссылки на изображения, потому что встраивание изображений не поддерживалось. Таким образом, URL ссылается на свой источник. Сообщество позже превратило URL-адреса во встроенные изображения без редактирования какой-либо ссылки на него. 4-летний топ-комментарий также указывает на то, на что вы указываете. Посмотрите: stackoverflow.com/posts/184780/revisions Почему бы просто не отредактировать цитату в ответе самостоятельно? Я могу быть недоступен в следующий раз, когда у кого-то будет жалоба на мой 10-летний стиль письма.
Дламблин
156

Короче, это зависит от того, что указывает на что. В мелкой копии объект B указывает на местоположение объекта A в памяти. При глубоком копировании все вещи в ячейке памяти объекта A копируются в ячейку памяти объекта B.

Эта вики статья имеет отличную схему.

http://en.wikipedia.org/wiki/Object_copy

helloandre
источник
115

Попробуйте рассмотреть следующее изображение

введите описание изображения здесь

Например, Object.MemberwiseClone создает ссылку для мелкого копирования

и используя интерфейс ICloneable, вы можете получить глубокое копирование, как описано здесь

Александр
источник
28
Одна картинка стоит тысячи слов.
Леви Фуллер
6
О, мальчик, пришел сюда, чтобы выяснить смысл. Это единственный ответ, который помог.
Каран Сингх
1
Это самое простое и пока показывает только то, что необходимо.
hina10531
1
лучшая иллюстрация
Мухаммед Наяб
69

Специально для разработчиков iOS:

Если Bэто мелкая копия из A, то для примитивных данных это , как B = [A assign];и для объектов , это как B = [A retain];

B и A указывают на одну и ту же ячейку памяти

Если Bэто глубокая копия из A, то это какB = [A copy];

B и A указывают на разные области памяти

Адрес памяти B такой же, как и у A

Б имеет то же содержание, что и А

Абхишек Беди
источник
8
«Адрес памяти Б такой же, как и у А» - как получилось?
2
В Deep Copy «адрес памяти B НЕ совпадает с адресом A»
ismail baig
60

Мелкая копия: копирует значения элементов из одного объекта в другой.

Deep Copy: копирует значения элементов из одного объекта в другой.
                     Любые объекты указателя дублируются и копируются.

Пример:

class String
{
     int   size;
     char* data;
};

String  s1("Ace");   // s1.size = 3 s1.data=0x0000F000

String  s2 = shallowCopy(s1);
 // s2.size =3 s2.data = 0X0000F000
String  s3 = deepCopy(s1);
 // s3.size =3 s3.data = 0x0000F00F
 //                      (With Ace copied to this location.)
Мартин Йорк
источник
47

Я не видел короткого, легкого для понимания ответа здесь - поэтому я попробую.

При неглубоком копировании любой объект, на который указывает источник, также указывается адресатом (так что ссылочные объекты не копируются).

При глубокой копии любой объект, на который указывает источник, копируется, а на копию указывает пункт назначения (так что теперь будет 2 из каждого ссылочного объекта). Это повторяется в дереве объектов.

Билл К
источник
36

{Представьте себе два объекта: A и B одного и того же типа _t (по отношению к C ++), и вы думаете о мелком / глубоком копировании A в B}

Shallow Copy: просто делает копию ссылки на A в B. Думайте об этом как о копии адреса A. Таким образом, адреса A и B будут одинаковыми, то есть они будут указывать на одну и ту же ячейку памяти, то есть содержимое данных.

Глубокая копия: просто делает копию всех членов A, выделяет память в другом месте для B и затем назначает скопированные элементы B для достижения глубокой копии. Таким образом, если A становится несуществующим, B все еще действует в памяти. Правильным термином для использования будет клонирование, когда вы знаете, что оба они абсолютно одинаковы, но все же различны (т.е. хранятся как два разных объекта в пространстве памяти). Вы также можете предоставить свою обертку для клонов, где вы можете решить, используя список включения / исключения, какие свойства выбрать при глубоком копировании. Это довольно распространенная практика при создании API.

Вы можете сделать мелкую копию ONLY_IF, если вы понимаете, какие ставки включены . Когда у вас есть огромное количество указателей для работы в C ++ или C, создание мелкой копии объекта действительно ДЕЙСТВИТЕЛЬНО плохая идея.

EXAMPLE_OF_DEEP COPY_ Например, когда вы пытаетесь выполнить обработку изображений и распознавание объектов, вам необходимо скрыть «неактуальное и повторяющееся движение» из областей обработки. Если вы используете указатели изображений, то у вас может быть спецификация для сохранения этих изображений маски. СЕЙЧАС ... если вы делаете поверхностную копию изображения, когда ссылки указателя УБИВАЮТСЯ из стека, вы теряете ссылку и ее копию, то есть в какой-то момент произойдет ошибка нарушения доступа. В этом случае вам понадобится глубокая копия вашего изображения путем клонирования. Таким образом, вы можете получить маски на случай, если они понадобятся вам в будущем.

EXAMPLE_OF_SHALLOW_COPY Я не очень хорошо осведомлен по сравнению с пользователями в StackOverflow, поэтому не стесняйтесь удалять эту часть и приводите хороший пример, если можете уточнить. Но я действительно думаю, что не стоит делать поверхностное копирование, если вы знаете, что ваша программа будет работать в течение бесконечного периода времени, то есть непрерывной операции push-pop над стеком с вызовами функций. Если вы демонстрируете что-то любителю или начинающему человеку (например, учебные материалы по C / C ++), то это, вероятно, хорошо. Но если вы используете приложение, такое как система наблюдения и обнаружения, или Sonar Tracking System, вы не должны продолжать поверхностно копировать ваши объекты, потому что это рано или поздно убьет вашу программу.

ha9u63ar
источник
32
char * Source = "Hello, world.";

char * ShallowCopy = Source;    

char * DeepCopy = new char(strlen(Source)+1);
strcpy(DeepCopy,Source);        

«ShallowCopy» указывает на то же место в памяти, что и «Source». «DeepCopy» указывает на другое место в памяти, но его содержимое одинаково.

Джон Диблинг
источник
22

Что такое мелкая копия?

Мелкая копия - побитовая копия объекта. Создается новый объект, который имеет точную копию значений в исходном объекте. Если какие-либо поля объекта являются ссылками на другие объекты, копируются только ссылочные адреса, т. Е. Копируется только адрес памяти.Мелкая копия

На этом рисунке MainObject1есть поля field1типа int и ContainObject1типа ContainObject. Когда вы делаете мелкую копию MainObject1, MainObject2создается с field2содержащим скопированное значение field1и по-прежнему указывающим на ContainObject1себя. Обратите внимание, что поскольку field1это тип примитива, его значение копируется, field2но, поскольку ContainedObject1это объект, он MainObject2все еще указывает на ContainObject1. Таким образом, любые изменения, внесенные ContainObject1в, MainObject1будут отражены в MainObject2.

Теперь, если это мелкая копия, давайте посмотрим, что такое глубокая копия?

Что такое Deep Copy?

Глубокая копия копирует все поля и создает копии динамически распределенной памяти, на которую указывают поля. Глубокое копирование происходит, когда объект копируется вместе с объектами, на которые он ссылается. Deep Copy

На этом рисунке MainObject1 имеет поля field1типа int и ContainObject1типа ContainObject. Когда вы делаете глубокую копию MainObject1, MainObject2создается с field2содержащим скопированное значение field1и ContainObject2содержащим скопированное значение ContainObject1. Обратите внимание, что любые изменения, внесенные ContainObject1в MainObject1, не будут отражены в MainObject2.

хорошая статья

Атиш Шимпи
источник
это не ваша вина, хотя этот пример относится к тому, field3который, когда в состоянии попытаться понять что-то настолько глубокое, как эта проблема, где же находится этот № 3 в этом примере ContainObject2 ?
Robb_2015
16

В объектно-ориентированном программировании тип включает в себя коллекцию полей-членов. Эти поля могут храниться либо по значению, либо по ссылке (т. Е. Указатель на значение).

В мелкой копии создается новый экземпляр типа, а значения копируются в новый экземпляр. Ссылочные указатели также копируются как значения. Поэтому ссылки указывают на исходные объекты. Любые изменения в элементах, которые хранятся по ссылке, отображаются как в оригинале, так и в копии, поскольку не было сделано ни одной копии ссылочного объекта.

При глубоком копировании поля, которые хранятся по значению, копируются, как и раньше, но указатели на объекты, сохраненные по ссылке, не копируются. Вместо этого делается глубокая копия ссылочного объекта, и указатель на новый объект сохраняется. Любые изменения, внесенные в эти объекты, на которые есть ссылки, не влияют на другие копии объекта.

Джеффри Л Уитледж
источник
12

«ShallowCopy» указывает на то же место в памяти, что и «Source». «DeepCopy» указывает на другое место в памяти, но его содержимое одинаково.

GovindaRaju
источник
Это немного вводит в заблуждение. Как поверхностная, так и глубокая копия будут копировать объект в новое место в памяти, глубокая также будет копировать дочерние объекты, тогда как мелкая будет просто иметь новые объекты, ссылающиеся на старые дочерние объекты. Трудно читать, не ссылаясь на оригинальный объект.
Билл К
10

Неглубокое клонирование:
определение: «Неглубокая копия объекта копирует« основной »объект, но не копирует внутренние объекты». Когда пользовательский объект (например, Employee) имеет только примитивные переменные типа String, тогда вы используете Shallow Cloning.

Employee e = new Employee(2, "john cena");
Employee e2=e.clone();

Вы возвращаетесь super.clone();в переопределенном методе clone (), и ваша работа закончена.

Глубокое клонирование :
определение: «В отличие от мелкой копии, глубокая копия является полностью независимой копией объекта».
Означает, что объект Employee содержит другой пользовательский объект:

Employee e = new Employee(2, "john cena", new Address(12, "West Newbury", "Massachusetts");

Затем вы должны написать код для клонирования объекта Address также в переопределенном методе clone (). В противном случае объект Address не будет клонирован, и это приведет к ошибке при изменении значения Address в клонированном объекте Employee, который также отражает исходный объект.

Арун Раадж
источник
8
var source = { firstName="Jane", lastname="Jones" };
var shallow = ShallowCopyOf(source);
var deep = DeepCopyOf(source);
source.lastName = "Smith";
WriteLine(source.lastName); // prints Smith
WriteLine(shallow.lastName); // prints Smith
WriteLine(deep.lastName); // prints Jones
Dour High Arch
источник
Это не хороший пример. Мелкие копии в основном используются для быстрого копирования объектов, без копирования данных, но как только объекту нужно изменить общие данные, его глубокая копия берется. Ваш пример, скорее всего, запутает начинающих.
CMircea
это работает только в тех языках, которые используют указатели для представления строк. Пункт, который пытается создать DHA, заключается в том, что поверхностное копирование дублирует только указатели на идентичный (единственный) исходный контент, в то время как глубокое копирование также клонирует ссылочный контент указателей. Оба метода копируют содержимое поверхности. Если язык хранит строки в виде поверхностного литерального содержимого, например, внутри заголовка WAV, этот пример не будет работать. Обратите внимание, что это, вероятно, слишком требовательно для большинства реальных проблем, которые не являются эзотерическими.
DragonLord
8

Deep Copy

Глубокая копия копирует все поля и создает копии динамически распределенной памяти, на которую указывают поля. Глубокое копирование происходит, когда объект копируется вместе с объектами, на которые он ссылается.

Мелкая копия

Мелкая копия - побитовая копия объекта. Создается новый объект, который имеет точную копию значений в исходном объекте. Если какие-либо поля объекта являются ссылками на другие объекты, копируются только ссылочные адреса, т. Е. Копируется только адрес памяти.

Сунил Кумар Саху
источник
К сожалению, эта ссылка больше не работает - теперь она указывает на статью от февраля 2019 года, касающуюся веб-дизайна (разве автор ясновидящий?).
PhilPhil
7

Shallow Copy - Ссылочная переменная внутри оригинальных и мелко скопированных объектов имеет ссылку на общий объект.

Deep Copy - Ссылочная переменная внутри оригинальных и глубоко скопированных объектов имеет ссылку на другой объект.

клон всегда делает мелкую копию.

public class Language implements Cloneable{

    String name;
    public Language(String name){
        this.name=name;
    }

    public String getName() {
        return name;
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}

основной класс следующий-

public static void main(String args[]) throws ClassNotFoundException, CloneNotSupportedException{

      ArrayList<Language> list=new ArrayList<Language>();
      list.add(new Language("C"));
      list.add(new Language("JAVA"));

      ArrayList<Language> shallow=(ArrayList<Language>) list.clone();
      //We used here clone since this always shallow copied.

      System.out.println(list==shallow);

      for(int i=0;i<list.size();i++)
      System.out.println(list.get(i)==shallow.get(i));//true

      ArrayList<Language> deep=new ArrayList<Language>();
      for(Language language:list){
          deep.add((Language) language.clone());
      }
      System.out.println(list==deep);
      for(int i=0;i<list.size();i++)
          System.out.println(list.get(i)==deep.get(i));//false

} 

OutPut выше будет

ложь правда правда

ложь ложь ложь

Любое изменение, сделанное в оригинальном объекте, отразится на мелком объекте, а не на глубоком объекте.

  list.get(0).name="ViSuaLBaSiC";
  System.out.println(shallow.get(0).getName()+"  "+deep.get(0).getName());

OutPut- ViSuaLBaSiC C


источник
7

Я хотел бы привести пример, а не формальное определение.

var originalObject = { 
    a : 1, 
    b : 2, 
    c : 3,
};

Этот код показывает мелкую копию :

var copyObject1 = originalObject;

console.log(copyObject1.a);         // it will print 1 
console.log(originalObject.a);       // it will also print 1 
copyObject1.a = 4; 
console.log(copyObject1.a);           //now it will print 4 
console.log(originalObject.a);       // now it will also print 4

var copyObject2 = Object.assign({}, originalObject);

console.log(copyObject2.a);        // it will print 1 
console.log(originalObject.a);      // it will also print 1 
copyObject2.a = 4; 
console.log(copyObject2.a);        // now it will print 4 
console.log(originalObject.a);      // now it will print 1

Этот код показывает глубокую копию :

var copyObject2 = Object.assign({}, originalObject);

console.log(copyObject2.a);        // it will print 1 
console.log(originalObject.a);      // it will also print 1 
copyObject2.a = 4; 
console.log(copyObject2.a);        // now it will print 4 
console.log(originalObject.a);      // !! now it will print 1 !!
Вивек Мехта
источник
Я получаю1 1 4 4 4 4 4 4
Суреш Праджапати
в глубокой копии, сделайте copyObject.a = 8 и затем проверьте. надеюсь, вы получите правильный ответ.
Вивек Мехта
5
struct sample
{
    char * ptr;
}
void shallowcpy(sample & dest, sample & src)
{
    dest.ptr=src.ptr;
}
void deepcpy(sample & dest, sample & src)
{
    dest.ptr=malloc(strlen(src.ptr)+1);
    memcpy(dest.ptr,src.ptr);
}
notytony
источник
5

Проще говоря, мелкая копия похожа на вызов по ссылке, а глубокая копия похожа на вызов по значению

В вызове по ссылке как формальные, так и фактические параметры функции относятся к одной и той же ячейке памяти и значению.

В вызове по значению формальные и фактические параметры функции относятся к разным ячейкам памяти, но имеют одно и то же значение.

Сантош
источник
5

Представьте, что есть два массива с именами arr1 и arr2.

arr1 = arr2;   //shallow copy
arr1 = arr2.clone(); //deep copy
PeerNet
источник
5

Мелкая копия создает новый составной объект и вставляет в него ссылки на исходный объект.

В отличие от мелкого копирования, deepcopy создает новый составной объект, а также вставляет копии исходных объектов исходного составного объекта.

Давайте возьмем пример.

import copy
x =[1,[2]]
y=copy.copy(x)
z= copy.deepcopy(x)
print(y is z)

Над кодом печатается ЛОЖЬ.

Давай посмотрим как.

Исходный составной объект x=[1,[2]](называется составным, потому что у него есть объект внутри объекта (Inception))

введите описание изображения здесь

как вы можете видеть на картинке, внутри списка есть список.

Затем мы создаем поверхностную копию, используя y = copy.copy(x). Здесь Python создает новый составной объект, но объекты внутри него указывают на оригинальные объекты.

введите описание изображения здесь

В изображении он создал новую копию для внешнего списка. но внутренний список остается таким же, как и исходный.

Теперь мы создаем его глубокую копию z = copy.deepcopy(x). Что Python делает здесь, так это то, что он создаст новый объект для внешнего списка, а также для внутреннего списка. как показано на рисунке ниже (выделено красным).

введите описание изображения здесь

В конце кода печатается False, так как y и z не являются одинаковыми объектами.

НТН.

Sushant
источник
2

При поверхностном копировании создается новый объект, а затем копируются нестатические поля текущего объекта в новый объект. Если поле является типом значения -> выполняется побитовая копия поля; для ссылочного типа -> ссылка копируется, а ссылочный объект - нет; поэтому исходный объект и его клон ссылаются на один и тот же объект.

Глубокая копия создает новый объект, а затем копирует нестатические поля текущего объекта в новый объект. Если поле является типом значения -> выполняется побитовая копия поля. Если поле является ссылочным типом -> выполняется новая копия упомянутого объекта. Клонируемые классы должны быть помечены как [Сериализуемые].

Раджарам Шелар
источник
2

Взято из [блога]: http://sickprogrammersarea.blogspot.in/2014/03/technical-interview-questions-on-c_6.html

Глубокое копирование включает использование содержимого одного объекта для создания другого экземпляра того же класса. В глубокой копии два объекта могут содержать одну и ту же информацию, но целевой объект будет иметь свои собственные буферы и ресурсы. уничтожение любого объекта не повлияет на оставшийся объект. Перегруженный оператор присваивания создаст глубокую копию объектов.

Мелкое копирование включает в себя копирование содержимого одного объекта в другой экземпляр того же класса, создавая таким образом зеркальное отображение. Благодаря прямому копированию ссылок и указателей эти два объекта будут совместно использовать одно и то же внешнее содержимое другого объекта, что будет непредсказуемым.

Объяснение:

Используя конструктор копирования, мы просто копируем значения данных по элементам. Этот метод копирования называется мелким копированием. Если объект является простым классом, состоящим из встроенных типов и без указателей, это будет приемлемо. Эта функция будет использовать значения и объекты, и ее поведение не будет изменено с мелкой копией, копируются только адреса указателей, являющихся членами, а не значение, на которое указывает адрес. Значения данных объекта затем будут случайно изменены функцией. Когда функция выходит из области видимости, копия объекта со всеми его данными извлекается из стека.

Если объект имеет какие-либо указатели, необходимо выполнить глубокое копирование. При глубоком копировании объекта память выделяется для объекта в свободном хранилище, а указанные элементы копируются. Глубокая копия используется для объектов, которые возвращаются из функции.

Сантош
источник
2

Чтобы добавить больше к другим ответам,

  • поверхностное копирование объекта выполняет копирование по значению для свойств на основе типов значений и копирование по ссылке для свойств на основе ссылочных типов.
  • Deep Copy объекта выполняет копирование по значению для свойств на основе типов значений, а также копирование по значению для свойств на основе ссылочных типов в глубине иерархии (ссылочных типов).
VS1
источник
2

Мелкая копия не создаст новую ссылку, но глубокая копия создаст новую ссылку.

Вот программа для объяснения глубокой и мелкой копии.

public class DeepAndShollowCopy {
    int id;
    String name;
    List<String> testlist = new ArrayList<>();

    /*
    // To performing Shallow Copy 
    // Note: Here we are not creating any references. 
      public DeepAndShollowCopy(int id, String name, List<String>testlist)
       { 

       System.out.println("Shallow Copy for Object initialization");
       this.id = id; 
       this.name = name; 
       this.testlist = testlist; 

       }
    */  

    // To performing Deep Copy 
    // Note: Here we are creating one references( Al arraylist object ). 
    public DeepAndShollowCopy(int id, String name, List<String> testlist) {
        System.out.println("Deep Copy for Object initialization");
        this.id = id;
        this.name = name;
        String item;
        List<String> Al = new ArrayList<>();
        Iterator<String> itr = testlist.iterator();
        while (itr.hasNext()) {
            item = itr.next();
            Al.add(item);
        }
        this.testlist = Al;
    }


    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        list.add("Java");
        list.add("Oracle");
        list.add("C++");
        DeepAndShollowCopy copy=new DeepAndShollowCopy(10,"Testing", list);
        System.out.println(copy.toString());
    }
    @Override
    public String toString() {
        return "DeepAndShollowCopy [id=" + id + ", name=" + name + ", testlist=" + testlist + "]";
    }
}
Лова Читтумури
источник
1

Копирование статей:

Массив является классом, что означает, что это ссылочный тип, поэтому array1 = array2 приводит к двум переменным, которые ссылаются на один и тот же массив.

Но посмотрите на этот пример:

  static void Main()
    {
        int[] arr1 = new int[] { 1, 2, 3, 4, 5 }; 
        int[] arr2 = new int[] { 6, 7, 8, 9, 0 };

        Console.WriteLine(arr1[2] + " " + arr2[2]);
        arr2 = arr1;
        Console.WriteLine(arr1[2] + " " + arr2[2]); 
        arr2 = (int[])arr1.Clone();
        arr1[2] = 12;
        Console.WriteLine(arr1[2] + " " + arr2[2]);
    }

мелкий клон означает, что копируется только память, представленная клонированным массивом.

Если массив содержит объекты типа значения, значения копируются ;

если массив содержит ссылочный тип, копируются только ссылки, поэтому в результате появляются два массива, члены которых ссылаются на одни и те же объекты .

Чтобы создать глубокую копию - там, где ссылочный тип дублируется, вы должны пройти через массив и клонировать каждый элемент вручную.

lukaszk
источник
Я не знаю о других языках, но в C # / VB поверхностное копирование массива типов значений не копирует значения. Два массива ссылаются на одни и те же объекты. Добавьте кнопку в форму и добавьте этот код, чтобы увидеть:private void button1_Click(object sender, EventArgs e) { int[] arr1 = new int[]{1,2,3,4,5}; int[] arr2 = new int[]{6,7,8,9,0}; MessageBox.Show(arr1[2] + " " + arr2[2]); arr2 = arr1; MessageBox.Show(arr1[2] + " " + arr2[2]); arr1[2] = 12; MessageBox.Show(arr1[2] + " " + arr2[2]); }
DeanOC
Вы правы, я исправил свой ответ, чтобы быть более точным, используя клон на массивах. Вы абсолютно правы, что «поверхностное копирование массива типов значений не копирует значения», но использование клона в массиве делает. Я пытался объяснить это, попробуйте. Спасибо
Лукашк
1

Я пришел к пониманию из следующих строк.

При мелком копировании поля типа значения объекта (int, float, bool) копируются в целевой объект, а ссылочные типы объекта (строка, класс и т. Д.) Копируются как ссылки в целевой объект. В этой цели ссылочные типы будут указывать на место в памяти исходного объекта.

Глубокая копия копирует значение объекта и ссылочные типы в полную новую копию целевых объектов. Это означает, что как типам значений, так и ссылочным типам будут выделены новые ячейки памяти.

Найас Субраманян
источник
0

Помимо всех приведенных выше определений, еще один и наиболее часто используемый глубокий экземпляр находится в конструкторе копирования (или перегружающем операторе присваивания) класса.

Мелкая копия -> это когда вы не предоставляете конструктор копирования. Здесь копируется только объект, но копируются не все члены класса.

Глубокое копирование -> это когда вы решили реализовать конструктор копирования или присвоение перегрузки в своем классе и разрешить копирование всех членов класса.

MyClass& MyClass(const MyClass& obj) // copy constructor for MyClass
{
          // write your code, to copy all the members and return the new object
}
MyClass& operator=(const MyClass& obj) // overloading assignment operator,
{
          // write your code, to copy all the members and return the new object
}
Авинаш Гауд, Нью-Джерси
источник
0

Конструктор копирования используется для инициализации нового объекта ранее созданным объектом того же класса. По умолчанию компилятор написал поверхностную копию. Мелкое копирование работает хорошо, когда динамическое выделение памяти не задействовано, потому что, когда задействовано динамическое выделение памяти, оба объекта будут указывать на одну и ту же область памяти в куче. Поэтому, чтобы устранить эту проблему, мы написали глубокое копирование, чтобы оба объекта имели свою собственную копию атрибутов. в памяти. Для того, чтобы прочитать подробности с полными примерами и пояснениями, вы можете увидеть в статье конструкторы C ++ .

royal52
источник