В чем разница между глубокой копией и мелкой копией?
В чем разница между глубокой копией и мелкой копией?
Ответы
Ответ 1
Мелкие копии дублируют как можно меньше. Неглубокая копия коллекции - это копия структуры коллекции, а не элементов. С неглубокой копией две коллекции теперь разделяют отдельные элементы.
Глубокие копии дублируют все. Глубокая копия коллекции - это две коллекции, в которых дублируются все элементы в исходной коллекции.
Ответ 2
Ширина против Глубины; мыслить в терминах дерева ссылок с вашим объектом в качестве корневого узла.
Мелкий:
Переменные A и B относятся к разным областям памяти, когда B присваивается A, две переменные относятся к одной и той же области памяти. Более поздние модификации содержимого любого из них немедленно отражаются в содержимом другого, поскольку они разделяют содержимое.
Deep:
Переменные A и B относятся к различным областям памяти, когда B присваивается A значения в области памяти, на которые указывает A, копируются в область памяти, на которую указывает B. Более поздние модификации содержимого либо остаются уникальными для A или B; содержание не передается.
Ответ 3
Короче говоря, это зависит от того, что указывает на что. В мелкой копии объект B указывает на местоположение объекта A в памяти. В глубокой копии все вещи в объекте. Место памяти скопировано в объект памяти B.
Эта статья wiki имеет большую диаграмму.
http://en.wikipedia.org/wiki/Object_copy
Ответ 4
Специально для разработчиков iOS:
Если B
является мелкой копией A
, то для примитивных данных это похоже на B = [A assign];
, а для объектов - как B = [A retain]
;
B и A указывают на ту же ячейку памяти
Если B
является глубокой копией A
, то это похоже на B = [A copy];
B и A указывают на разные ячейки памяти
Адрес памяти B такой же, как у
B имеет то же содержимое, что и A
Ответ 5
Попробуйте рассмотреть следующее изображение
Например Object.MemberwiseClone создает ссылку неглубокая
и используя ICloneable интерфейс, вы можете получить глубокую копию, как описано здесь
Ответ 6
Мелкая копия: копирует значения элементов из одного объекта в другой.
Глубокая копия: копирует значения элементов из одного объекта в другой.
; .
Пример:
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.)
Ответ 7
Я не видел короткого, легкого для понимания ответа здесь, поэтому я попробую.
С помощью неглубокой копии любой объект, на который указывает источник, также указывается адресатом (так что никакие ссылочные объекты не копируются).
С глубокой копией любой объект, на который указывает источник, копируется, а на копию указывается пункт назначения (так что теперь будет 2 каждого объекта, на который делается ссылка). Это повторяет дерево объектов.
Ответ 8
Просто для легкого понимания вы можете следовать этой статье:
https://www.cs.utexas.edu/~scottm/cs307/handouts/deepCopying.htm
Неверное копирование:
Deep Copy:
Ответ 9
{Представьте себе два объекта: A и B того же типа _t (относительно С++), и вы думаете о неглубоко/глубоком копировании A в B}
Мелкая копия:
Просто делает копию ссылки на A в B. Подумайте об этом как копию A Address.
Таким образом, адреса A и B будут такими же, то есть они будут указывать на то же место памяти, то есть на содержимое.
Глубокая копия:
Просто делает копию всех членов A, выделяет память в другом месте для B, а затем назначает скопированные элементы B для достижения глубокой копии. Таким образом, если A становится несуществующим, B все еще действует в памяти. Правильный термин для использования будет клонированием, где вы знаете, что оба они абсолютно одинаковы, но все же разные (т.е. Хранятся как два разных объекта в пространстве памяти). Вы также можете предоставить свою клон-обертку, где вы можете выбрать через список включения/исключения, какие свойства выбрать во время глубокой копии. Это довольно распространенная практика при создании API-интерфейсов.
Вы можете выбрать "Мелкая копия" ONLY_IF, которую вы понимаете. Когда у вас есть огромное количество указателей на С++ или C, выполнение мелкой копии объекта ДЕЙСТВИТЕЛЬНО - плохая идея.
EXAMPLE_OF_DEEP COPY _ Примером является то, что когда вы пытаетесь выполнить обработку изображений и распознавание объектов, вам нужно замаскировать "Irrelevant and Reetitive Motion" из ваших областей обработки. Если вы используете указатели изображений, у вас может быть спецификация для сохранения этих изображений масок. СЕЙЧАС... если вы сделаете мелкую копию изображения, когда ссылки указателя будут убиты из стека, вы потеряли ссылку и ее копию, то есть в какой-то момент будет ошибка времени выполнения. В этом случае вам нужна глубокая копия вашего изображения с помощью CLONING. Таким образом, вы можете получить маски в случае, если они вам понадобятся в будущем.
EXAMPLE_OF_SHALLOW_COPY Я не очень осведомлен по сравнению с пользователями в StackOverflow, поэтому не стесняйтесь удалять эту часть и ставить хороший пример, если вы можете уточнить. Но я действительно думаю, что неплохо делать мелкую копию, если вы знаете, что ваша программа будет работать в течение бесконечного периода времени, т.е. Непрерывная операция push-pop поверх стека с вызовами функций. Если вы демонстрируете что-то любителю или новичку (например, учебное пособие C/С++), то, вероятно, все в порядке. Но если вы используете приложение, такое как система наблюдения и обнаружения, или система отслеживания сонара, вы не должны хранить мелкие копии своих объектов, потому что они рано или поздно убьют вашу программу.
Ответ 10
char * Source = "Hello, world.";
char * ShallowCopy = Source;
char * DeepCopy = new char(strlen(Source)+1);
strcpy(DeepCopy,Source);
"ShallowCopy" указывает на то же место в памяти, что и "Источник".
"DeepCopy" указывает на другое место в памяти, но содержимое одного и того же.
Ответ 11
Что такое мелкая копия?
Мелкая копия - это бит-копия объекта. Создается новый объект, который имеет точную копию значений в исходном объекте. Если какое-либо из полей объекта является ссылкой на другие объекты, копируются только ссылочные адреса, т.е. Копируется только адрес памяти.
На этом рисунке MainObject1
есть поля field1
типа int и ContainObject1
типа ContainObject
. Когда вы делаете мелкую копию MainObject1
, MainObject2
создается с field2
, содержащим скопированное значение field1
и все еще указывающим на ContainObject1
. Заметим, что поскольку field1
имеет примитивный тип, его значение копируется в field2
, но поскольку ContainedObject1
является объектом, MainObject2
все еще указывает на ContainObject1
. Поэтому любые изменения, сделанные в ContainObject1
в MainObject1
, будут отражены в MainObject2
.
Теперь, если это мелкая копия, давайте посмотрим, какая глубокая копия?
Что такое Deep Copy?
Глубокая копия копирует все поля и создает копии динамически выделенной памяти, на которые указывают поля. Глубокая копия возникает, когда объект копируется вместе с объектами, к которым он относится.
На этом рисунке MainObject1 имеют поля field1
типа int и ContainObject1
типа ContainObject
. Когда вы делаете глубокую копию MainObject1
, MainObject2
создается с field2
, содержащим скопированное значение field1
и ContainObject2
, содержащее скопированное значение ContainObject1
. Обратите внимание, что любые изменения, сделанные в ContainObject1
в MainObject1
, не будут отображаться в MainObject2
.
хорошая статья
Ответ 12
В объектно-ориентированном программировании тип включает в себя набор полей-членов. Эти поля могут быть сохранены либо по значению, либо по ссылке (т.е. Указателю на значение).
В мелкой копии создается новый экземпляр типа и значения копируются в новый экземпляр. Ориентировочные указатели также копируются точно так же, как и значения. Поэтому ссылки указывают на исходные объекты. Любые изменения в элементах, которые хранятся по ссылке, отображаются как в оригинале, так и в копии, поскольку копия объекта ссылки не была сделана.
В глубокой копии поля, которые хранятся по значению, копируются по-прежнему, но указатели на объекты, хранящиеся по ссылке, не копируются. Вместо этого делается глубокая копия объекта, на который ссылается, и сохраняется указатель на новый объект. Любые изменения, внесенные в эти объекты, не будут влиять на другие копии объекта.
Ответ 13
"ShallowCopy" указывает на то же место в памяти, что и "Источник". "DeepCopy" указывает на другое место в памяти, но содержимое одного и того же.
Ответ 14
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
Ответ 15
Deep Copy
Глубокая копия копирует все поля и создает копии динамически распределенной памяти, на которую указывают поля. Глубокое копирование происходит, когда объект копируется вместе с объектами, на которые он ссылается.
Мелкая копия
Мелкая копия - побитовая копия объекта. Создается новый объект, который имеет точную копию значений в исходном объекте. Если какие-либо поля объекта являются ссылками на другие объекты, копируются только ссылочные адреса, т.е. Копируется только адрес памяти.
Ответ 16
Неглубокое клонирование:
Определение: "Неглубокая копия объекта копирует" основной объект ", но не копирует внутренние объекты". Когда пользовательский объект (например, Employee) имеет только примитивные переменные типа String, вы используете Shallow Cloning.
Employee e = new Employee(2, "john cena");
Employee e2=e.clone();
Вы возвращаете super.clone();
в методе overridden clone() и ваша работа завершена.
Глубокое клонирование:
Определение: "В отличие от мелкой копии глубокая копия является полностью независимой копией объекта".
Значит, если объект Employee имеет другой пользовательский объект:
Employee e = new Employee(2, "john cena", new Address(12, "West Newbury", "Massachusetts");
Затем вам нужно написать код, чтобы клонировать объект "Адрес", а также в методе overridden clone(). В противном случае объект Address не будет клонировать и вызывает ошибку при изменении значения адреса в клонированном объекте Employee, который также отражает исходный.
Ответ 17
Неверная копия. Справочная переменная внутри исходных и неглубококопированных объектов имеет ссылку на общий объект.
Глубокая копия. Ссылка на исходные и глубоко скопированные объекты ссылается на другой объект.
клон всегда делает мелкую копию.
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 выше будет -
false true true
false false false
Любое изменение, сделанное в исходном объекте, будет отражено в мелком объекте не в глубоком объекте.
list.get(0).name="ViSuaLBaSiC";
System.out.println(shallow.get(0).getName()+" "+deep.get(0).getName());
OutPut - ViSuaLBaSiC C
Ответ 18
Я хотел бы привести пример, а не формальное определение.
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 !!
Ответ 19
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);
}
Ответ 20
В простых условиях мелкая копия похожа на Call By Reference, а Deep Copy похожа на Call By Value
В режиме вызова по ссылке как формальные, так и фактические параметры функции относятся к тому же месту памяти и значению.
В разделе "Вызов по значению" как формальные, так и фактические параметры функций относятся к разным ячейкам памяти, но имеют одинаковое значение.
Ответ 21
Представьте, что существуют два массива, называемые arr1 и arr2.
arr1 = arr2; //shallow copy
arr1 = arr2.clone(); //deep copy
Ответ 22
Неверное копирование создает новый объект, а затем копирует нестатические поля текущего объекта в новый объект. Если поле является типом значения → выполняется побитовая копия поля; для ссылочного типа → ссылка копируется, но упомянутый объект не является; поэтому исходный объект и его клон относятся к одному и тому же объекту.
Копия Deep создает новый объект, а затем копирует нестатические поля текущего объекта в новый объект. Если поле является значением типа → выполняется побитовая копия поля. Если поле является ссылочным типом → , выполняется новая копия упомянутого объекта. Классы, подлежащие клонированию, должны быть помечены как [Serializable].
Ответ 23
Взято из [blog]: http://sickprogrammersarea.blogspot.in/2014/03/technical-interview-questions-on-c_6.html
Глубокая копия предполагает использование содержимого одного объекта для создания другого экземпляра того же класса. В глубокой копии оба объекта могут содержать одну и ту же информацию, но целевой объект будет иметь свои собственные буферы и ресурсы. уничтожение любого объекта не повлияет на оставшийся объект. Перегруженный оператор присваивания создаст глубокую копию объектов.
Неверная копия предполагает копирование содержимого одного объекта в другой экземпляр того же класса, создавая зеркальное изображение. Благодаря прямому копированию ссылок и указателей два объекта будут разделять одно и то же содержимое, содержащее внешний контент другого объекта, чтобы быть непредсказуемым.
Объяснение:
Используя конструктор копирования, мы просто копируем элемент данных по члену. Этот метод копирования называется мелкой копией. Если объект является простым классом, состоящим из встроенных типов и без указателей, это будет приемлемым. Эта функция будет использовать значения и объекты, и ее поведение не будет изменено с помощью мелкой копии, копируются только адреса указателей, которые являются членами, а не значение, на которое указывает адрес. Значения данных объекта затем будут непреднамеренно изменены функцией. Когда функция выходит за пределы области видимости, копия объекта со всеми его данными удаляется из стека.
Если объект имеет какие-либо указатели, необходимо выполнить глубокую копию. С глубокой копией объекта память выделяется для объекта в свободном хранилище, а отмеченные элементы копируются. Для объектов, возвращаемых функцией, используется глубокая копия.
Ответ 24
Чтобы добавить другие ответы,
- Мелкая копия объекта выполняет копирование по значению для типов значений
основанные на свойствах, и копировать по ссылке для свойств ссылочных типов.
- Глубокая копия объекта выполняет копирование по значению для типов значений на основе
свойства, а также копировать по значению для ссылочных типов на основе
свойства в глубине иерархии (ссылочных типов)
Ответ 25
Мелкая копия не создаст новую ссылку, но глубокая копия создаст новую ссылку.
Вот программа для объяснения глубокой и мелкой копии.
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 + "]";
}
}
Ответ 26
Неглубокая копия создает новый составной объект и вставляет его ссылки в исходный объект.
В отличие от мелкой копии, deepcopy создает новый составной объект, а также вставляет копии исходных объектов исходного составного объекта.
Давайте возьмем пример.
import copy
x =[1,[2]]
y=copy.copy(x)
z= copy.deepcopy(x)
print(y is z)
Выше кода печатает FALSE.
Посмотрим, как.
Оригинальный составной объект x=[1,[2]]
(называемый составным, поскольку он имеет объект внутри объекта (начало))
как вы можете видеть на изображении, есть список внутри списка.
Затем мы создаем мелкую копию с помощью y = copy.copy(x)
. Что здесь делает python, он создаст новый составной объект, но объекты внутри них указывают на объекты orignal.
В изображении создана новая копия для внешнего списка. но внутренний список остается таким же, как и исходный.
Теперь мы создаем глубину его использования с помощью z = copy.deepcopy(x)
. то, что здесь делает python, он создаст новый объект для внешнего списка, а также для внутреннего списка. как показано на рисунке ниже (красный выделен).
В конце кода печатается False
, так как y и z не являются одними и теми же объектами.
НТН.
Ответ 27
Копирование арари:
Array - это класс, который означает, что он является ссылочным типом, поэтому array1 = результаты массива
в двух переменных, которые ссылаются на один и тот же массив.
Но посмотрите на этот пример:
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]);
}
мелкий клон означает, что копируется только память, представленная клонированным массивом.
Если массив содержит объекты типа значения, значения копируются;
, если массив содержит ссылочный тип, копируются только ссылки - поэтому в результате есть два массива, члены которых ссылаются на те же объекты.
Чтобы создать дублированный тип ссылки с копией, где необходимо дублировать, вы должны пройти через массив и клонировать каждый элемент вручную.
Ответ 28
Добавление ко всем приведенным выше определениям, еще одна и наиболее часто используемая глубокая копия, находится в конструкторе копирования (или перегружает присваивающий оппортер) класса.
Неверная копия → это когда вы не предоставляете конструктор копирования. Здесь копируется только объект, но не все члены класса копируются.
Deep copy → - это когда вы решили реализовать конструктор копирования или перегрузку в своем классе и разрешить копирование всех членов класса.
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
}
Ответ 29
Конструктор копирования используется для инициализации нового объекта с ранее созданным объектом того же класса. По умолчанию компилятор написал мелкую копию. Мелкая копия отлично работает, когда динамическое распределение памяти не задействовано, поскольку при распределении динамической памяти оба объекта указывают на одну и ту же ячейку памяти в куче, поэтому для удаления этой проблемы мы написали глубокую копию, чтобы оба объекта имели свою собственную копию атрибутов в памяти.
Чтобы прочитать подробности с полными примерами и пояснениями, вы можете увидеть статью конструкторы С++.
Ответ 30
Объектная копия - это процесс, в котором объект данных имеет свои атрибуты, скопированные на другой объект того же типа данных. В .Net Неверная копия и глубокая копия используются для копирования данных между объектами.
Неглубокая копия объекта - это новый объект, переменные экземпляра которого идентичны старому объекту. В .Net неглубокая копия выполняется объектным методом MemberwiseClone().
Глубокая копия предназначена для копирования всех элементов объекта, которые включают в себя элементы ссылочного типа со ссылкой на ссылочные типы ссылочного типа, которые содержат ссылки на ячейку памяти, которая содержит данные, а не содержащие сами данные.
Подробнее о...... глубокая копия и мелкая копия
Rj