Derin bir kopya ile sığ bir kopya arasındaki fark nedir?


Yanıtlar:


760

Sığ kopyalar mümkün olduğunca az kopya. Bir koleksiyonun sığ bir kopyası, elemanların değil, toplama yapısının bir kopyasıdır. Sığ bir kopyayla, iki koleksiyon artık tek tek öğeleri paylaşıyor.

Derin kopyalar her şeyi kopyalar. Bir koleksiyonun derin kopyası, orijinal koleksiyondaki tüm öğelerin kopyalandığı iki koleksiyondur.


.NET MemberwiseClone () uygulaması geleneksel anlamda sığ kopyalamadan daha fazlasını yapabilir
Lu55

5
Ayrıca , yalnızca bir kısmını çoğaltan ( burada bir örnek ) karışık kopyalar (sadece tembel kopya gibi değil ) olduğunu unutmayın! ;)
cregox

Yani X'in sığ bir kopyası X'deki öğeleri değiştirebilir ancak derin bir kopya değişemez mi?
cezaevi

1
koleksiyon yapısı nedir?
Tatlım

1
@Honey Koleksiyonları, birden fazla veri öğesini depolayan çeşitli veri yapıları olabilir. Python'da demet, liste, sözlük vb. Var
Murphy

850

Genişlik ve Derinlik; kök düğüm olarak nesnenizle bir referans ağacı açısından düşünün.

Sığ:

Before Copy Shallow Copying Shallow Done

A ve B değişkenleri farklı bellek alanlarını ifade eder, B A'ya atandığında iki değişken aynı bellek alanını ifade eder. Her ikisinin içeriğindeki daha sonra yapılan değişiklikler, içeriği paylaştıkça diğerlerinin içeriğine anında yansır.

Derin:

Before Copy Deep Copying Deep Done

A ve B değişkenleri, B'ye A atandığında, bellek alanındaki A'nın B'nin işaret ettiği bellek alanına kopyalanacağı değerleri belirlediği farklı bellek alanlarını ifade eder. Daha sonraki içeriklerde yapılacak değişiklikler A veya B'ye özgü kalır; içerik paylaşılmaz.


32
İşte sizin için bağlam dışında bir anlam ifade etmemesi durumunda bu çizimden gelen wikipedia makalesi en.wikipedia.org/wiki/Object_copy#Shallow_copy
corbin

4
Sığ kopya durumunda, B ve B dizisinde herhangi bir değişiklik yaparsak, A ve B her ikisi de aynı bellek konumuna işaret ettiğinden A dizisine yansıtılacaktır.
tek3

3
Tek satırda, referansa göre kopyası, değere göre kopyası. Cevabın doğru olup olmadığından emin değilim!
Mannu

2
doğrudan alıntı olmadan wikipedia'dan alınan görüntüler
jasonleonhard

9
@jasonleonhard 9 yıl önce resimlere URL'ler ekledim çünkü resimleri gömmek desteklenmedi. Böylece URL kaynağını gösterdi. Topluluk daha sonra URL'leri, üzerinde bir tür alıntıyı düzenlemeden gömülü resimlere dönüştürdü. 4 yaşındaki üst yorum da ne işaret ediyor. Bir göz atın: stackoverflow.com/posts/184780/revisions Neden sadece cevaba yapılan bir alıntıyı kendiniz düzenlemiyorsunuz? Birisi benim 10 yaşındaki yazma tarzı hakkında bazı şikayet var yakın zaman olmayabilir.
dlamblin

156

Kısacası, neyi neye işaret ettiğine bağlıdır. Sığ bir kopyada, B nesnesi, A nesnesinin bellekteki konumunu işaret eder. Derin kopyada, A nesnesinin bellek konumundaki her şey B nesnesinin bellek konumuna kopyalanır.

Bu wiki makalesinde harika bir diyagram var.

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


113

Aşağıdaki resmi düşünmeye çalışın

enter image description here

Örneğin, Object.MemberwiseClone sığ bir kopya bağlantısı oluşturur

ve ICloneable arabirimini kullanarak burada açıklandığı gibi derin kopya alabilirsiniz.


28
Bir resim bin kelime değerinde bir olup.
Levi Fuller

6
Oh evlat, anlamını bulmak için buraya geldi. Yardımcı olan tek cevap bu.
Karan Singh

1
Bu en basit olanıdır ve sadece neyin gerekli olduğunu gösterir.
hina10531

1
en iyi illüstrasyon
Muhammed Nayab

69

Özellikle iOS Geliştiricileri için:

Eğer Bbir olan sığ kopya ait Abenzediğini ilkel veri için daha sonra, B = [A assign];ve bunun nasıl nesneler için B = [A retain];

B ve A aynı bellek konumuna işaret ediyor

Eğer Bbir olan derin kopya ait A, o zaman gibidirB = [A copy];

B ve A farklı bellek konumlarını gösterir

B bellek adresi A ile aynı

B, A ile aynı içeriğe sahiptir


8
"B bellek adresi A ile aynı" - Nasıl olur?

2
Derin
Kopyada

60

Sığ kopya: Üye değerlerini bir nesneden diğerine kopyalar.

Derin Kopya: Üye değerlerini bir nesneden diğerine kopyalar.
                     İşaretçi nesneleri çoğaltılır ve Derin Kopyalanır.

Misal:

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

Burada kısa, anlaşılması kolay bir cevap görmedim - bu yüzden deneyeceğim.

Sığ bir kopyada, kaynak tarafından işaret edilen herhangi bir nesne de hedef tarafından işaret edilir (böylece referans alınan hiçbir nesne kopyalanmaz).

Derin bir kopya ile, kaynak tarafından işaret edilen herhangi bir nesne kopyalanır ve kopya hedef tarafından işaretlenir (bu nedenle artık her başvurulan nesneden 2 tane olacaktır). Bu, nesne ağacını geri çeker.



36

{İki nesneyi düşünün: A ve B aynı tür _t (C ++ ile ilgili olarak) ve A'dan B'ye sığ / derin kopyalamayı düşünüyorsunuz}

Sığ Kopya: A'ya yapılan referansın B'ye bir kopyasını almanız yeterlidir. Bunu A'nın Adresinin bir kopyası olarak düşünün. Böylece, A ve B adresleri aynı olacaktır, yani aynı bellek konumuna, yani veri içeriğine işaret edeceklerdir.

Derin kopya: A'nın tüm üyelerinin bir kopyasını oluşturur, belleği B için farklı bir konuma ayırır ve sonra kopyalanan üyeleri derin kopya elde etmek için B'ye atar. Bu şekilde, eğer A mevcut değilse B hafızasında hala geçerlidir. Kullanılacak doğru terim, her ikisinin de tamamen aynı, ancak yine de farklı olduğunu bildiğiniz klonlamadır (yani bellek alanında iki farklı varlık olarak saklanır). Klon sarmalayıcıyı, derin kopyalama sırasında hangi özellikleri seçeceğiniz dahil etme / hariç tutma listesi aracılığıyla karar verebileceğiniz bir yerde de sağlayabilirsiniz. API oluştururken bu oldukça yaygın bir uygulamadır.

İlgili riskleri anladığınız ONLY_IF sığ bir kopya yapmayı seçebilirsiniz. C ++ veya C ile uğraşmak için çok sayıda işaretçiniz olduğunda, bir nesnenin sığ bir kopyasını yapmak GERÇEKTEN kötü bir fikirdir.

EXAMPLE_OF_DEEP COPY_ Bir örnek olarak, görüntü işleme ve nesne tanıma yapmaya çalıştığınızda, işleme alanlarınızdan "Alakasız ve Tekrarlanan Hareket" i maskelemeniz gerekir. Görüntü işaretçileri kullanıyorsanız, bu maske görüntülerini kaydetme özelliğiniz olabilir. ŞİMDİ ... görüntünün sığ bir kopyasını yaparsanız, işaretçi başvuruları yığından ÖLDÜRÜLDÜĞÜNDE, başvuruyu ve kopyasını kaybettiniz, yani bir noktada erişim ihlali çalışma zamanı hatası olacaktır. Bu durumda, ihtiyacınız olan şey resminizin CLONING ile derin bir kopyasıdır. Bu şekilde, gelecekte ihtiyacınız olması durumunda maskeleri geri alabilirsiniz.

EXAMPLE_OF_SHALLOW_COPY StackOverflow'daki kullanıcılara kıyasla son derece bilgili değilim, bu yüzden bu bölümü silmekten çekinmeyin ve açıklığa kavuşturabiliyorsanız iyi bir örnek verin. Ama gerçekten programınızın sonsuz bir süre için çalışacağını biliyorsanız, yani fonksiyon çağrıları ile yığın üzerinde sürekli "push-pop" işlemi yapacağını biliyorsanız, sığ kopya yapmak iyi bir fikir değildir. Amatör veya acemi bir kişiye (örneğin C / C ++ öğretici şeyler) bir şey gösteriyorsanız, muhtemelen iyidir. Ancak, gözetleme ve algılama sistemi veya Sonar İzleme Sistemi gibi bir uygulama çalıştırıyorsanız, programınızı er ya da geç öldürecekleri için nesnelerinizi sığ kopyalamaya devam etmeniz gerekmez.


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

char * ShallowCopy = Source;    

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

'ShallowCopy' bellekte 'Source' ile aynı yeri gösterir. 'DeepCopy' bellekteki farklı bir yeri gösterir, ancak içerik aynıdır.


22

Sığ Kopya nedir?

Sığ kopya, bir nesnenin bit bilge bir kopyasıdır. Orijinal nesnedeki değerlerin tam bir kopyasına sahip yeni bir nesne oluşturulur. Nesnenin alanlarından herhangi biri başka nesnelere başvuruysa, yalnızca referans adresleri kopyalanır, yani yalnızca bellek adresi kopyalanır.Sığ Kopya

Bu şekilde, MainObject1alana sahiptir field1tipi int, ve ContainObject1Çeşidi ContainObject. Eğer yüzeysel bir kopyasını yaptığınızda MainObject1, MainObject2oluşturulur field2ve kopyalanan değeri içeren field1işaret hareketsiz ve ContainObject1kendisi. Çünkü bu Not field1ilkel tiptedir, değeri kopyalanır field2ancak o zamandan beri ContainedObject1, bir amacı, MainObject2halen işaret ContainObject1. Yapılan değişikliklerin Yani ContainObject1içinde MainObject1yansıyacaktırMainObject2 .

Şimdi bu sığ kopya ise, derin kopya ne görelim?

Derin Kopya nedir?

Derin bir kopya tüm alanları kopyalar ve dinamik olarak tahsis edilmiş belleğin alanların gösterdiği kopyalarını yapar. Bir nesne, başvurduğu nesnelerle birlikte kopyalandığında derin bir kopya oluşur. Derin Kopya

Bu şekilde, MainObject1 alanlara sahip field1int türünde ve ContainObject1Çeşidi ContainObject. Eğer derin bir kopyasını yaptığınızda MainObject1, MainObject2oluşturulur field2ve kopyalanan değerini içeren field1ve ContainObject2kopyalanmış değerini içeren ContainObject1. Yapılan değişiklikleri Not ContainObject1içinde MainObject1görünmeyeceği MainObject2.

iyi makale


Bu örnek, ifade eder gerçi bu senin suçun değil bir field3hangi zaman gerçekleşen bu örnekte olduğu 3. olduğunu denemek ve bu konu olarak derin olarak kavrar şey bir pozisyonda ContainObject2 ?
Robb_2015

16

Nesneye yönelik programlamada, bir tür üye alanlarının bir koleksiyonunu içerir. Bu alanlar, değere veya referansa göre (yani bir değere işaretçi) depolanabilir.

Sığ bir kopyada, türün yeni bir örneği oluşturulur ve değerler yeni örneğe kopyalanır. Referans göstergeleri de tıpkı değerler gibi kopyalanır. Bu nedenle, başvurular orijinal nesnelere işaret eder. Başvuru ile depolanan üyelerde yapılan değişiklikler, başvurulan nesnenin hiçbir kopyası yapılmadığından hem orijinal hem de kopyada görünür.

Derin bir kopyada, değere göre depolanan alanlar önceki gibi kopyalanır, ancak başvuru ile depolanan nesnelere yönelik işaretçiler kopyalanmaz. Bunun yerine, başvurulan nesnenin derin bir kopyası oluşturulur ve yeni nesneye yönelik bir işaretçi saklanır. Başvurulan nesnelerde yapılan değişiklikler, nesnenin diğer kopyalarını etkilemez.


12

'ShallowCopy' bellekte 'Source' ile aynı yeri gösterir. 'DeepCopy' bellekteki farklı bir yeri gösterir, ancak içerik aynıdır.


Bu biraz yanıltıcı. Hem sığ hem de derin bir kopya nesneyi bellekteki yeni bir konuma kopyalar, bir derin de alt nesneleri kopyalarken, sığ bir nesnenin sadece eski çocuklara başvurmasını sağlar. Orijinal nesneye başvurmadan okumak zor.
Bill K

10

Sığ Klonlama:
Tanım: "Bir nesnenin sığ bir kopyası 'ana' nesneyi kopyalar, ancak iç nesneleri kopyalamaz." Özel bir nesne (örn. Çalışan) sadece ilkel olduğunda, Dize türü değişkenleri sonra Sığ Klonlama kullanırsınız.

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

super.clone();Geçersiz kılınan clone () yöntemine dönersiniz ve işiniz sona erer.

Deep Cloning :
Tanım: "Sığ kopyadan farklı olarak, derin kopya bir nesnenin tamamen bağımsız bir kopyasıdır."
Bir Employee nesnesinin başka bir özel nesne tutması anlamına gelir:

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

Daha sonra, geçersiz klon () yönteminde 'Adres' nesnesini klonlamak için kod yazmanız gerekir. Aksi takdirde, Address nesnesi klonlanmaz ve klonlanan Employee nesnesindeki Adres değerini değiştirdiğinizde hataya neden olur, bu da orijinali yansıtır.


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

Bu iyi bir örnek değil. Sığ kopyalar çoğunlukla verileri kopyalamadan nesnelerin hızlı kopyalanması için kullanılır, ancak bir nesnenin paylaşılan verileri değiştirmesi gerektiğinde, bunun derin bir kopyası alınır. Örneğiniz muhtemelen yeni başlayanları karıştırır.
CMircea

bu yalnızca dizeleri temsil etmek için işaretçiler kullanan dillerde çalışır. DHA'nın yapmaya çalıştığı nokta, sığ kopyanın işaretçileri yalnızca özdeş (tekil) orijinal içeriğe kopyalaması, derin kopya ise işaretçilerin başvurulan içeriğini klonlamasıdır. Her iki yöntem de yüzey içeriğini kopyalar. Dil, dizeleri, örneğin bir WAV üstbilgisi içinde yüzey değişmez içeriği olarak depolarsa, bu örnek çalışmaz. Bunun ezoterik olmayan çoğu gerçek yaşam problemi için muhtemelen çok seçici olduğunu unutmayın.
DragonLord

8

Derin Kopya

Derin bir kopya tüm alanları kopyalar ve dinamik olarak ayrılmış belleğin alanların gösterdiği kopyalarını yapar. Bir nesne, başvurduğu nesnelerle birlikte kopyalandığında derin bir kopya oluşur.

Sığ Kopya

Sığ kopya, bir nesnenin bit bilge bir kopyasıdır. Orijinal nesnedeki değerlerin tam bir kopyasına sahip yeni bir nesne oluşturulur. Nesnenin alanlarından herhangi biri başka nesnelere başvuruysa, yalnızca başvuru adresleri kopyalanır, yani yalnızca bellek adresi kopyalanır.


Bu bağlantı ne yazık ki artık çalışmıyor - şimdi Şubat 2019'dan web tasarımı ile ilgili bir makaleye işaret ediyor (yazar basiretçi değilse?).
PhilPhil

7

Sığ Kopya - Orijinal ve sığ kopyalanan nesnelerin içindeki referans değişkeni, ortak nesneye başvuruda bulunur .

Derin Kopya - Orijinal ve derin kopyalanan nesnelerin içindeki başvuru değişkeni, farklı nesneye başvuruda bulunur .

klon her zaman sığ kopya yapar.

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

ana sınıf takip ediyor-

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

} 

Yukarıdakilerin çıkışı:

yanlış doğru doğru

yanlış yanlış yanlış

Orijinal nesnede yapılan herhangi bir değişiklik, derin nesnede olmayan sığ nesneye yansır.

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

Çıkış - ViSuaLBaSiC C


7

Resmi tanımdan ziyade örnek vermek istiyorum.

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

Bu kod sığ bir kopya gösterir :

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

Bu kod derin bir kopyasını gösterir :

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 !!

Ben alıyorum1 1 4 4 4 4 4 4
Suresh Prajapati

derin kopyada copyObject.a = 8 yapın ve kontrol edin. Umarım doğru cevabı alırsın.
Vivek Mehta

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

Basit bir ifadeyle, sığ bir kopya referans ile çağrıya ve derin bir kopya değere göre çağrıya benzer

Referansla Arama'da, bir işlevin hem resmi hem de gerçek parametreleri aynı bellek konumuna ve değere karşılık gelir.

Değere Göre Çağrıda, bir işlevin hem resmi hem de gerçek parametreleri farklı bellek konumuna karşılık gelir, ancak aynı değere sahiptir.


5

Arr1 ve arr2 adında iki dizi olduğunu düşünün.

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

5

Sığ bir kopya yeni bir bileşik nesne oluşturur ve referanslarını orijinal nesneye bu nesneye ekler.

Sığ kopyadan farklı olarak, deepcopy yeni bileşik nesne oluşturur ve ayrıca orijinal bileşik nesnenin orijinal nesnelerinin kopyalarını ekler.

Bir örnek verelim.

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

Yukarıdaki kod YANLIŞ yazdırır.

Nasıl olduğunu görelim.

Orijinal bileşik nesne x=[1,[2]](nesnenin içinde nesne olduğu için bileşik olarak adlandırılır (Başlangıç))

resim açıklamasını buraya girin

resimde gördüğünüz gibi, listenin içinde bir liste var.

Sonra kullanarak sığ bir kopyasını oluştururuz y = copy.copy(x). Python'un yaptığı şey, yeni bir bileşik nesne oluşturacak, ancak içindeki nesneler orignal nesnelere işaret ediyor.

resim açıklamasını buraya girin

Resimde dış liste için yeni bir kopya oluşturdu. ancak iç liste orijinal listeyle aynı kalır.

Şimdi kullanarak bunun derin kopyasını yaratıyoruz z = copy.deepcopy(x). Python'un yaptığı şey, hem dış liste hem de iç liste için yeni bir nesne yaratacak. aşağıdaki resimde gösterildiği gibi (kırmızı vurgulanmış).

resim açıklamasını buraya girin

Sonunda kod yazdırılır False , çünkü y ve z aynı nesne değildir.

HTH.


2

Sığ kopyalama yeni bir nesne oluşturur ve ardından geçerli nesnenin statik olmayan alanlarını yeni nesneye kopyalar. Alan bir değer türüyse -> alanın biter bir kopyası gerçekleştirilir; Bir için başvuru türü -> referans kopyalanır, ancak atıfta bulunulan nesne kopyalanmaz; bu nedenle orijinal nesne ve klonu aynı nesneyi belirtir.

Derin kopya yeni bir nesne oluşturur ve ardından geçerli nesnenin statik olmayan alanlarını yeni nesneye kopyalar. Alan bir değer türüyse -> alanın biter bir kopyası gerçekleştirilir. Alan bir başvuru türüyse -> belirtilen nesnenin yeni bir kopyası gerçekleştirilir. Klonlanacak sınıflar [Serileştirilebilir] olarak işaretlenmelidir.


2

[Blog] 'dan alınmıştır: http://sickprogrammersarea.blogspot.in/2014/03/technical-interview-questions-on-c_6.html

Derin kopya , aynı sınıfın başka bir örneğini oluşturmak için bir nesnenin içeriğinin kullanılmasını içerir. Derin bir kopyada, iki nesne aynı bilgileri içerebilir ancak hedef nesnenin kendi arabellekleri ve kaynakları olacaktır. her iki nesnenin de imhası kalan nesneyi etkilemeyecektir. Aşırı yüklenmiş atama operatörü nesnelerin derin bir kopyasını oluşturur.

Sığ kopya , bir nesnenin içeriğinin aynı sınıfın başka bir örneğine kopyalanmasını ve böylece bir ayna görüntüsü oluşturulmasını içerir. Referansların ve işaretçilerin doğrudan kopyalanması nedeniyle, iki nesne öngörülemeyen diğer nesnenin harici olarak aynı içeriğini paylaşacaktır.

Açıklama:

Bir kopya yapıcı kullanarak, veri değerlerini üye üyeye kopyalarız. Bu kopyalama yöntemine sığ kopya denir. Nesne, yerleşik tiplerden ve işaretçilerden oluşan basit bir sınıfsa, bu kabul edilebilir. Bu işlev değerleri ve nesneleri kullanır ve davranışı sığ bir kopyayla değiştirilmez, yalnızca üye olan işaretçilerin adresleri kopyalanır ve adresin işaret ettiği değer değil. Nesnenin veri değerleri, işlev tarafından yanlışlıkla değiştirilecektir. İşlev kapsam dışına çıktığında, nesnenin tüm verileriyle birlikte kopyası yığından çıkarılır.

Nesnenin herhangi bir işaretçisi varsa, derin bir kopya yürütülmesi gerekir. Bir nesnenin derin kopyasıyla, serbest depodaki nesne için bellek ayrılır ve işaret edilen öğeler kopyalanır. Bir işlevden döndürülen nesneler için derin bir kopya kullanılır.


2

Diğer yanıtlara daha fazlasını eklemek için,

  • bir nesnenin Sığ Kopyası, değer türlerine dayalı özellikler için değere göre kopyalama ve referans türlerine dayalı özellikler için başvuruya göre kopyalama gerçekleştirir.
  • bir nesnenin Derin Kopyası, değer türlerine dayalı özellikler için değere göre kopyalamanın yanı sıra hiyerarşinin (referans türlerinin) derinliklerinde referans türlerine dayalı özelliklere göre değere göre kopyalamayı gerçekleştirir

2

Sığ kopya yeni referans oluşturmaz ancak derin kopya yeni referans oluşturur.

İşte derin ve sığ kopyayı açıklayan program.

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

Ararys kopyalama:

Dizi bir sınıftır, yani başvuru türü olduğu için array1 = dizi2 aynı diziye başvuran iki değişkenle sonuçlanır.

Ancak şu örneğe bakın:

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

sığ klon , yalnızca klonlanmış dizi tarafından temsil edilen belleğin kopyalandığı anlamına gelir.

Dizi değer türü nesneler içeriyorsa, değerler kopyalanır ;

dizi başvuru türü içeriyorsa, yalnızca başvurular kopyalanır; sonuç olarak, üyeleri aynı nesnelere başvuran iki dizi vardır .

Referans türünün çoğaltıldığı derin bir kopya oluşturmak için dizi arasında döngü yapmalı ve her öğeyi manuel olarak klonlamalısınız.


Ben diğer diller hakkında bilmiyorum ama C # / VB, sığ gelmez değer türleri dizisi kopyalama değil değerlerini kopyalayın. İki dizi aynı nesnelere karşılık gelir. Bir forma düğme ekleyin ve görmek için bu kodu ekleyin: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

haklısın, cevabımı dizilerde klon kullanarak daha kesin olmak için düzelttim. "Bir dizi değer türünün sığ kopyalanması değerleri kopyalamıyor" ama dizide klon kullanmanın kesinlikle haklı olduğunu. Bunu anlatmaya çalıştım, dene. Thanks
lukaszk

1

Aşağıdaki satırlardan anlamaya başladım.

Sığ kopya, bir nesne değeri türü (int, float, bool) alanlarını hedef nesneye kopyalar ve nesnenin referans türleri (dize, sınıf vb.) Hedef nesnede referanslar olarak kopyalanır . Bu hedefte referans türleri, kaynak nesnenin hafıza konumuna işaret edecektir.

Derin kopya, bir nesnenin değerini ve referans türlerini hedef nesnelerin tamamen yeni bir kopyasına kopyalar. Bu, hem değer türlerine hem de referans türlerine yeni bir bellek konumu tahsis edileceği anlamına gelir.


0

Yukarıdaki tüm tanımlara ek olarak, bir ve daha yaygın olarak kullanılan bir derin kopya, sınıfın kopya yapıcısında (veya aşırı yükleme atama işleyicisinde) bulunur.

Sığ kopya ->, kopya oluşturucu sağlamadığınız zamandır. Burada yalnızca nesne kopyalanır, ancak sınıfın tüm üyeleri kopyalanmaz.

Derin kopya -> sınıfınızda kopya oluşturucu veya aşırı yük ataması uygulamaya karar verdiğinizde ve sınıfın tüm üyelerini kopyalamaya izin verdiğiniz zamandır.

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

Kopya oluşturucu, yeni nesneyi aynı sınıfta önceden oluşturulmuş nesne ile başlatmak için kullanılır. Varsayılan olarak derleyici sığ bir kopya yazdı. Dinamik bellek tahsisi dahil olmadığında sığ kopya iyi çalışır çünkü dinamik bellek tahsisi söz konusu olduğunda, her iki nesne de bir yığındaki aynı bellek konumuna işaret eder, Bu nedenle bu sorunu kaldırmak için her iki nesnenin de kendi öznitelik kopyasına sahip olması için derin kopya yazdık bir bellekte. Ayrıntıları eksiksiz örneklerle ve açıklamalarla okumak için C ++ kurucuları makalesini görebilirsiniz .

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.