Чим відрізняється глибока копія від дрібної копії?


754

Чим відрізняється глибока копія від дрібної копії?


6
Під яку технологію вона потрапляє?
Суреш Варма

42
@SureshVarma, це концепція програмування!
Маніш Шрівастава

Відповіді:


759

Дрібні копії копіюються якомога менше. Неглибока копія колекції - це копія структури колекції, а не елементів. За допомогою дрібної копії дві колекції тепер діляться окремими елементами.

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


Можливо, реалізація .NET MemberwiseClone () зробить більше, ніж дрібне копіювання в загальноприйнятому розумінні
Lu55,

5
Майте на увазі, що є також змішані копії (не лише такі, як ледача копія ), що дублює лише частину ( ось примірник )! ;)
Крегокс

Отже, мілка копія X може змінювати елементи в X, але глибока копія не може?
каральниця

1
що таке структура колекції?
Мед

1
Колекції @Honey можуть бути різноманітними структурами даних, які зберігають кілька елементів даних. У python у нас є кортеж, перелік, делікатесні вироби тощо
Мерфі

850

Ширина проти глибини; подумайте з точки зору дерева посилань на ваш об'єкт як кореневий вузол.

Дрібні:

Before Copy Shallow Copying Shallow Done

Змінні A і B відносяться до різних областей пам'яті, коли B призначено A, дві змінні відносяться до тієї ж області пам'яті. Пізніші зміни змісту будь-якого миттєво відображаються на вмісті інших, оскільки вони поділяють вміст.

Глибокий:

Before Copy Deep Copying Deep Done

Змінні A і B відносяться до різних областей пам’яті, коли B призначаються A значення в області пам’яті, на яку вказується точка A, копіюється в область пам’яті, на яку вказує B. Пізніші зміни вмісту або залишаються унікальними для A або B; вміст не надається спільним.


32
Ось стаття у Вікіпедії, з якої ця ілюстрація походить, якщо вона не має сенсу для вас en.wikipedia.org/wiki/Object_copy#Shallow_copy
corbin

4
У разі дрібної копії, якщо ми внесемо зміни в масив B, чи будуть це відображені в масиві A, оскільки A&B обидва вказують на одне місце пам’яті?
tek3

3
В одному рядку його копія посиланням на копію за значенням. Не впевнений, чи відповідь правильна!
Mannu

2
зображення, безпосередньо взяті з вікіпедії без цитування
Jasonleonhard

9
@jasonleonhard Тому 9 років тому я просто розміщував URL-адреси для зображень, оскільки вбудовування зображень не підтримувалося. Таким чином, URL вказав своє джерело. Пізніше спільнота перетворила URL-адреси у вбудовані зображення, не редагуючи на ній якесь цитування. 4-річний верхній коментар також вказує на те, що ви вказуєте. Подивіться: stackoverflow.com/posts/184780/reitions Чому б просто не відредагувати цитату у відповідь самостійно? Мені може бути недоступним наступного разу, коли хтось скаржиться на мій 10-річний стиль письма.
dlamblin

156

Словом, це залежить від того, що вказує на що. У неглибокій копії об’єкт B вказує на об'єкт A в пам'яті. У глибокій копії все, що знаходиться в пам'яті об'єкта A, копіюється в пам'ять об'єкта B.

Ця стаття у вікі має чудову діаграму.

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


112

Спробуйте розглянути наступне зображення

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

Наприклад, 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 така сама, як і А

B має той самий вміст, що й А


8
"Адреса пам'яті B така ж, як і A" - Як це?

2
У Глибокій Копії "адреса пам'яті B НЕ така ж, як A"
Ісмаїл Байг

60

Неглибока копія: копіює значення учасника з одного об'єкта в інший.

Глибока копія: копіює значення учасників з одного об'єкта в інший.
                     Будь-які об’єкти вказівника дублюються та глибоко копіюються.

Приклад:

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}

Неглибока копія: просто робить копію посилання на А на Б. Подумайте про це як про копію Адреса А. Отже, адреси 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, ви не повинні тримати копіювати об’єкти навколо, оскільки це рано чи пізно знищить вашу програму.


32
char * Source = "Hello, world.";

char * ShallowCopy = Source;    

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

"ShallowCopy" вказує на те саме місце в пам'яті, що і "Джерело". 'DeepCopy' вказує на інше місце в пам'яті, але вміст той самий.


22

Що таке "Неглибока копія"?

Неглибока копія - це трохи розумна копія об'єкта. Створюється новий об’єкт, який має точну копію значень у вихідному об'єкті. Якщо будь-яке з полів об'єкта є посиланнями на інші об'єкти, копіюються лише довідкові адреси, тобто копіюється лише адреса пам'яті.Неглибока копія

На цьому малюнку MainObject1є поля field1типу int та ContainObject1type ContainObject. Коли ви робите дрібну копію MainObject1, MainObject2створюється з field2вмістом скопійованого значення field1та все ще вказує на ContainObject1себе. Зауважте, що оскільки field1має примітивний тип, його значення копіюється, field2але оскільки ContainedObject1є об'єктом, MainObject2все ще вказує на ContainObject1. Таким чином , будь-які зміни , внесені ContainObject1в MainObject1будуть відображені в MainObject2.

Тепер, якщо це неглибока копія, давайте подивимось, що таке глибока копія?

Що таке глибока копія?

Глибока копія копіює всі поля та робить копії динамічно розподіленої пам'яті, на яку вказують поля. Глибока копія виникає, коли об'єкт копіюється разом з об'єктами, на які він посилається. Глибока копія

На цьому малюнку MainObject1 мають поля field1типу int та ContainObject1type ContainObject. Коли ви робите глибоку копію MainObject1, MainObject2створюється, field2що містить скопійоване значення field1та ContainObject2містить скопійоване значення ContainObject1. Зауважте, що будь-які зміни, внесені ContainObject1в MainObject1, не відображатимуться в MainObject2.

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


це не ваша вина, хоча цей приклад посилається на те, field3що коли ти можеш спробувати зрозуміти щось настільки глибоке, як це питання, де це №3 у цьому прикладі має місце ContainObject2 ?
Robb_2015

16

В об'єктно-орієнтованому програмуванні тип включає колекцію полів-членів. Ці поля можуть зберігатися як за значенням, так і за посиланням (тобто, вказівником на значення).

У неглибокій копії створюється новий екземпляр типу і значення копіюються в новий екземпляр. Опорні покажчики також копіюються так само, як і значення. Тому посилання вказують на оригінальні об’єкти. Будь-які зміни членів, які зберігаються за посиланням, з'являються як в оригіналі, так і в копії, оскільки жодна копія згаданого об'єкта не була зроблена.

У глибокій копії поля, які зберігаються за значенням, копіюються, як і раніше, але вказівники на об'єкти, що зберігаються за посиланням, не копіюються. Натомість, із посилається на об'єкт робиться глибока копія і зберігається вказівник на новий об’єкт. Будь-які зміни, внесені до цих посилань, не впливатимуть на інші копії об'єкта.


12

"ShallowCopy" вказує на те саме місце в пам'яті, що і "Джерело". 'DeepCopy' вказує на інше місце в пам'яті, але вміст той самий.


Це трохи вводить в оману. І дрібна, і глибока копія копіюватиме об’єкт на нове місце в пам'яті, глибока також копіює дочірні об'єкти, тоді як на мілкой просто нові об'єкти відносяться до старих дітей. Важко читати, не посилаючись на оригінальний об’єкт.
Білл К

10

Дрібне клонування:
Визначення: "Неглибока копія об'єкта копіює" головний "об'єкт, але не копіює внутрішні об'єкти." Якщо користувацький об’єкт (наприклад, співробітник) має просто примітивні, змінні типу String, то ви використовуєте «Дрібне клонування».

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

Ви повертаєтесь super.clone();за методом перекритого clone () і ваше завдання закінчено.

Глибоке клонування :
Визначення: "На відміну від дрібної копії, глибока копія є повністю незалежною копією об'єкта."
Означає, коли об’єкт Співробітник містить інший спеціальний об’єкт:

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

Тоді вам доведеться написати код, щоб клонувати об’єкт "Адреса", а також методом перекритого clone (). В іншому випадку об'єкт 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

Це не гарний приклад. Неглибокі копії в основному використовуються для швидкого копіювання об'єктів без копіювання даних, але як тільки об’єкти потребують модифікації спільних даних, приймається глибока копія. Ваш приклад, швидше за все, бентежить початківців.
CMircea

це працює лише в мовах, які використовують покажчики для представлення рядків. Суть, яку намагається зробити DHA, полягає в тому, що дрібна копія лише копіює покажчики на однаковий (сингулярний) оригінальний вміст, тоді як глибока копія також клонує вміст покажчиків. Обидва способи копіюють поверхневий вміст. Якщо мова зберігає рядки як поверхневий буквальний вміст, наприклад, всередині заголовка WAV, цей приклад не буде працювати. Зауважте, що це, мабуть, занадто прискіпливо для більшості реальних проблем, які не є езотеричними.
DragonLord

8

Глибока копія

Глибока копія копіює всі поля та робить копії динамічно розподіленої пам'яті, на яку вказують поля. Глибока копія виникає, коли об'єкт копіюється разом з об'єктами, на які він посилається.

Неглибока копія

Неглибока копія - це трохи розумна копія об'єкта. Створюється новий об’єкт, який має точну копію значень у вихідному об'єкті. Якщо будь-яке з полів об'єкта посилається на інші об'єкти, просто копіюються посилання адреси, тобто копіюється лише адреса пам'яті.


Таке посилання, на жаль, більше не працює - воно тепер вказує на статтю від лютого 2019 року щодо веб-дизайну (хіба що автор не є ясновидцем?).
PhilPhil

7

Дрібна копія - Довідкова змінна всередині оригінальних та неглибоко скопійованих об'єктів має посилання на загальний об'єкт.

Глибока копія - довідкова змінна всередині оригінальних та глибоко скопійованих об'єктів має посилання на різний об'єкт.

клон завжди робить дрібну копію.

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

} 

Вихід з вище буде -

хибна правда правда

хибний хибний хибний

Будь-яка зміна в оригінальному об'єкті відображатиметься на мілководді, а не в глибокому об'єкті.

  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);
}

5

Простіше кажучи, «Неглибока копія» схожа на «Дзвінок за посиланням», а «Глибока копія» схожа на «Дзвінок за значенням»

У Call By Reference як формальні, так і фактичні параметри функції відносяться до одного і того ж місця пам'яті та значення.

У "Call By Value" як формальні, так і фактичні параметри функції відносяться до іншого місця пам'яті, але мають однакове значення.


5

Уявіть, що є два масиви, які називаються arr1 та arr2.

arr1 = arr2;   //shallow copy
arr1 = arr2.clone(); //deep copy

5

Неглибока копія конструює новий складний об’єкт і вставляє в нього посилання на оригінальний об'єкт.

На відміну від дрібної копії, deepcopy конструює новий складний об'єкт, а також вставляє копії оригінальних об'єктів оригінального складеного об'єкта.

Давайте візьмемо приклад.

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

Наведений вище код друкує FALSE.

Побачимо, як.

Оригінальний складений об'єкт x=[1,[2]](називається складовим, тому що він має об'єкт всередині об'єкта (Inception))

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

як ви бачите на зображенні, всередині є список.

Потім ми створюємо її неглибоку копію, використовуючи y = copy.copy(x). Що тут робить python, він створить новий складний об'єкт, але об'єкти всередині них вказують на оригінальні об'єкти.

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

Зображення створило нову копію для зовнішнього списку. але внутрішній список залишається таким же, як і оригінальний.

Тепер ми створюємо глибоку копію, використовуючи z = copy.deepcopy(x). що python робить тут, це створить новий об'єкт для зовнішнього списку, а також внутрішнього списку. як показано на зображенні нижче (виділено червоним кольором).

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

У кінці друкується код False, оскільки y і z не є однаковими об'єктами.

HTH.


2

Дрібне копіювання - це створення нового об'єкта, а потім копіювання нестатичних полів поточного об'єкта до нового об’єкта. Якщо поле є типом значення -> виконується побітова копія поля; для типу посилання -> посилання копіюється, але згаданий об'єкт не є; тому оригінальний об'єкт і його клон відносяться до одного і того ж об'єкта.

Глибока копія - це створення нового об'єкта, а потім копіювання нестатичних полів поточного об'єкта до нового об’єкта. Якщо поле є типом значення -> виконується побітна копія поля. Якщо поле є типовим типом -> виконується нова копія згаданого об'єкта. Класи, які потрібно клонувати, повинні бути позначені як [Serializable].


2

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

Глибока копія передбачає використання вмісту одного об’єкта для створення іншого екземпляра того ж класу. У глибокій копії два об'єкти можуть містити ht однакову інформацію, але цільовий об’єкт матиме власні буфери та ресурси. знищення будь-якого об'єкта не вплине на решту об'єкта. Перевантажений оператор призначення створив би глибоку копію об'єктів.

Дрібна копія передбачає копіювання вмісту одного об’єкта в інший екземпляр того ж класу, створюючи дзеркальне зображення. Завдяки прямому копіюванню посилань та покажчиків, два об'єкти матимуть однаковий вміст іншого об'єкта, який міститиме зовнішній вигляд, непередбачуваним.

Пояснення:

Використовуючи конструктор копій, ми просто копіюємо значення даних членами члена. Цей спосіб копіювання називається дрібною копією. Якщо об'єкт - простий клас, що складається з вбудованих типів і не має вказівників, це було б прийнятно. Ця функція використовує значення, і об'єкти, і її поведінка не буде змінена дрібною копією, копіюються лише адреси покажчиків, які є членами, а не значення, на яке вказує адреса. Значення даних об'єкта потім будуть ненавмисно змінені функцією. Коли функція виходить за межі, копія об'єкта з усіма його даними вискакує з стека.

Якщо на об'єкті є якісь покажчики, потрібно виконати глибоку копію. За допомогою глибокої копії об'єкта для об'єкта виділяється пам'ять у вільному зберіганні, а елементи, на які вказується, копіюються. Глибока копія використовується для об'єктів, які повертаються з функції.


2

Щоб додати більше інших відповідей,

  • Неглибока копія об’єкта виконує копіювання за значенням для властивостей, заснованих на значеннях, та копіювання за посиланням для властивостей на основі референтних типів.
  • Глибока копія об'єкта виконує копіювання за значенням для властивостей на основі типів, а також копіювання за значенням для властивостей, що базуються на еталонних типах, глибоко в ієрархії (для референтних типів)

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]);
    }

дрібний клон означає, що копіюється лише пам'ять, представлена ​​клонованим масивом.

Якщо масив містить об'єкти типу значень, значення копіюються ;

якщо масив містить тип посилання, копіюються лише посилання - в результаті виникають два масиви, члени яких посилаються на однакові об'єкти .

Щоб створити глибоку копію - там, де тип посилання дублюється, потрібно провести цикл через масив і клонувати кожен елемент вручну.


Я не знаю про інші мови, але в 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

Ви праві, я виправив свою відповідь, щоб бути більш точним, використовуючи клон на масивах. Ви абсолютно праві, що "дрібне копіювання масиву типів значень не копіює значення", але використання клону в масиві робить. Я намагався це пояснити, спробуйте. Дякую
lukaszk

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 ++ конструктори .

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.