Apa perbedaan antara salinan dalam dan salinan dangkal?


Jawaban:


762

Salinan dangkal duplikat sesedikit mungkin. Salinan dangkal koleksi adalah salinan struktur koleksi, bukan elemen. Dengan salinan dangkal, dua koleksi sekarang berbagi elemen individu.

Salinan yang dalam menggandakan semuanya. Salinan dalam koleksi adalah dua koleksi dengan semua elemen dalam koleksi asli digandakan.


Mungkin implementasi .NET MemberwiseClone () melakukan lebih dari menyalin dangkal dalam arti konvensional
Lu55

5
Perlu diingat ada juga salinan campuran (tidak hanya seperti salinan malas ), yang menduplikat hanya sebagian saja ( inilah contohnya )! ;)
cregox

Jadi salinan X yang dangkal dapat mengubah elemen dalam X tetapi salinan yang dalam tidak bisa?
punstress

1
apa itu struktur koleksi?
Sayang

1
@Honey Collections dapat berupa beragam struktur data yang menyimpan banyak item data. Dalam python kita memiliki tuple, daftar, kamus, dll
Murphy

852

Luasnya vs Kedalaman; berpikir dalam hal pohon referensi dengan objek Anda sebagai simpul root.

Dangkal:

Sebelum Menyalin Menyalin Dangkal Selesai Dangkal

Variabel A dan B merujuk ke area memori yang berbeda, ketika B ditugaskan ke A, kedua variabel merujuk ke area memori yang sama. Kemudian modifikasi pada konten keduanya langsung tercermin dalam konten lainnya, karena mereka berbagi konten.

Dalam:

Sebelum Menyalin Menyalin Dalam Selesai

Variabel A dan B merujuk ke area memori yang berbeda, ketika B ditugaskan ke A nilai-nilai di area memori yang A menunjuk ke disalin ke area memori yang B menunjuk. Kemudian modifikasi pada konten keduanya tetap unik untuk A atau B; isinya tidak dibagikan.


33
Berikut artikel wikipedia bahwa ilustrasi ini berasal dari dalam kasus itu tidak masuk akal di luar konteks untuk Anda en.wikipedia.org/wiki/Object_copy#Shallow_copy
corbin

4
Dalam hal salinan dangkal jika kita membuat perubahan dalam array B apakah itu akan tercermin dalam array A karena A & B keduanya menunjuk ke lokasi memori yang sama?
tek3

3
Dalam satu baris salinannya dengan referensi vs salinan dengan nilai. Tidak yakin apakah jawabannya benar!
Mannu

2
gambar langsung diambil dari wikipedia tanpa kutipan
jasonleonhard

10
@jasonleonhard Jadi 9 tahun yang lalu saya hanya menaruh url ke gambar karena menyematkan gambar tidak didukung. Demikian URL mengutip sumbernya. Komunitas kemudian membuat URL menjadi gambar yang disematkan tanpa mengedit semacam kutipan. Komentar teratas berusia 4 tahun juga menunjukkan apa yang Anda tunjukkan. Lihat: stackoverflow.com/posts/184780/revisi Mengapa tidak mengedit sendiri kutipan ke dalam jawaban? Saya mungkin tidak tersedia saat berikutnya seseorang memiliki keluhan tentang gaya penulisan saya yang berusia 10 tahun.
dlamblin

156

Singkatnya, itu tergantung pada poin apa. Dalam salinan dangkal, objek B menunjuk ke lokasi objek A di memori. Dalam penyalinan dalam, semua hal di lokasi memori objek A disalin ke lokasi memori objek B.

Artikel wiki ini memiliki diagram yang bagus.

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


114

Coba pertimbangkan gambar berikut

masukkan deskripsi gambar di sini

Misalnya Object.MemberwiseClone membuat salinan dangkal tautan

dan menggunakan antarmuka ICloneable Anda bisa mendapatkan salinan dalam seperti yang dijelaskan di sini


28
Sebuah gambar bernilai ribuan kata.
Levi Fuller

6
Oh boy, datang ke sini untuk mencari tahu artinya. Ini adalah satu-satunya jawaban yang membantu.
Karan Singh

1
Ini adalah yang paling sederhana namun hanya menunjukkan apa yang perlu.
hina10531

1
ilustrasi terbaik
Muhammad Nayab

69

Khusus Untuk Pengembang iOS:

Jika Badalah salinan dangkal dari A, maka untuk data primitif itu seperti B = [A assign];dan untuk benda-benda itu seperti B = [A retain];

B dan A menunjuk ke lokasi memori yang sama

Jika Badalah copy dalam dari A, maka itu sepertiB = [A copy];

B dan A menunjuk ke lokasi memori yang berbeda

Alamat memori B sama dengan A

B memiliki konten yang sama dengan A


8
"Alamat memori B sama dengan A" - Bagaimana bisa?

2
Dalam Salin Jauh, "alamat memori B TIDAK sama dengan A"
ismail baig

60

Salinan dangkal: Menyalin nilai anggota dari satu objek ke objek lainnya.

Salinan Jauh: Menyalin nilai anggota dari satu objek ke objek lainnya.
                     Setiap objek pointer digandakan dan Disalin Dalam.

Contoh:

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

Saya belum melihat jawaban yang singkat dan mudah dipahami di sini - jadi saya akan mencobanya.

Dengan salinan dangkal, objek apa pun yang ditunjukkan oleh sumber juga ditunjukkan oleh tujuan (sehingga tidak ada objek yang direferensikan disalin).

Dengan salinan yang dalam, objek apa pun yang ditunjuk oleh sumber akan disalin dan salinannya diarahkan ke tujuan (jadi sekarang akan ada 2 dari setiap objek yang direferensikan). Ini berulang ke pohon objek.



36

{Bayangkan dua objek: A dan B dengan jenis yang sama _t (sehubungan dengan C ++) dan Anda berpikir tentang penyalinan dangkal / dalam A ke B}

Salinan Dangkal: Cukup buat salinan referensi ke A ke B. Pikirkan sebagai salinan Alamat A. Jadi, alamat A dan B akan sama yaitu mereka akan menunjuk ke lokasi memori yang sama yaitu isi data.

Salinan dalam: Cukup buat salinan dari semua anggota A, alokasikan memori di lokasi yang berbeda untuk B dan kemudian tetapkan anggota yang disalin ke B untuk mendapatkan salinan yang dalam. Dengan cara ini, jika A menjadi tidak ada, B masih valid dalam memori. Istilah yang benar untuk digunakan adalah kloning, di mana Anda tahu bahwa keduanya sama, tetapi berbeda (yaitu disimpan sebagai dua entitas yang berbeda dalam ruang memori). Anda juga dapat memberikan pembungkus klon di mana Anda dapat memutuskan melalui daftar inklusi / pengecualian properti mana yang akan dipilih selama penyalinan dalam. Ini adalah praktik yang cukup umum ketika Anda membuat API.

Anda dapat memilih untuk melakukan Salinan Dangkal ONLY_IF Anda memahami taruhannya. Ketika Anda memiliki sejumlah besar pointer untuk berurusan dengan C ++ atau C, melakukan salinan objek yang dangkal benar - benar ide yang buruk.

EXAMPLE_OF_DEEP COPY_ Contohnya adalah, ketika Anda mencoba melakukan pemrosesan gambar dan pengenalan objek, Anda perlu menutupi "Gerakan Tidak Relevan dan Berulang-ulang" dari area pemrosesan Anda. Jika Anda menggunakan penunjuk gambar, maka Anda mungkin memiliki spesifikasi untuk menyimpan gambar topeng itu. SEKARANG ... jika Anda melakukan salinan gambar yang dangkal, ketika referensi pointer DIBUNUH dari tumpukan, Anda kehilangan referensi dan salinannya yaitu akan ada kesalahan runtime pelanggaran akses di beberapa titik. Dalam hal ini, yang Anda butuhkan adalah salinan gambar Anda yang dalam dengan mengkloningnya. Dengan cara ini Anda dapat mengambil topeng jika Anda membutuhkannya di masa depan.

EXAMPLE_OF_SHALLOW_COPY Saya tidak terlalu berpengetahuan dibandingkan dengan pengguna di StackOverflow jadi jangan ragu untuk menghapus bagian ini dan memberikan contoh yang baik jika Anda bisa mengklarifikasi. Tapi saya benar-benar berpikir itu bukan ide yang baik untuk melakukan copy dangkal jika Anda tahu bahwa program Anda akan berjalan untuk waktu yang tak terbatas yaitu operasi "push-pop" terus menerus selama stack dengan panggilan fungsi. Jika Anda mendemonstrasikan sesuatu kepada orang amatir atau pemula (mis. C / C ++ tutorial stuff) maka mungkin tidak apa-apa. Tetapi jika Anda menjalankan aplikasi seperti sistem pengawasan dan deteksi, atau Sistem Pelacakan Sonar, Anda tidak seharusnya terus menyalin objek Anda dengan dangkal karena itu akan membunuh program Anda cepat atau lambat.


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

char * ShallowCopy = Source;    

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

'ShallowCopy' menunjuk ke lokasi yang sama dalam memori seperti 'Sumber'. 'DeepCopy' menunjuk ke lokasi yang berbeda dalam memori, tetapi isinya sama.


22

Apa itu Salinan Dangkal?

Salinan dangkal adalah salinan objek yang sedikit bijaksana. Objek baru dibuat yang memiliki salinan tepat dari nilai-nilai di objek asli. Jika salah satu bidang objek referensi ke objek lain, hanya alamat referensi yang disalin yaitu, hanya alamat memori yang disalin.Salinan dangkal

Dalam gambar ini, MainObject1memiliki bidang field1tipe int, dan ContainObject1tipe ContainObject. Ketika Anda melakukan salinan dangkal MainObject1, MainObject2dibuat dengan field2berisi nilai yang disalin field1dan masih menunjuk ke ContainObject1dirinya sendiri. Perhatikan bahwa karena field1ini adalah tipe primitif, nilainya disalin field2tetapi karena ContainedObject1merupakan objek, MainObject2masih menunjuk ke ContainObject1. Jadi setiap perubahan yang dilakukan ContainObject1pada MainObject1akan tercermin dalam MainObject2.

Sekarang jika ini adalah salinan dangkal, mari kita lihat apa yang ada di dalamnya?

Apa itu Deep Copy?

Salinan yang dalam menyalin semua bidang, dan membuat salinan dari memori yang dialokasikan secara dinamis ditunjuk oleh bidang tersebut. Salinan dalam terjadi ketika suatu objek disalin bersama dengan objek yang dirujuk. Salinan Yang Dalam

Dalam gambar ini, MainObject1 memiliki bidang field1tipe int, dan ContainObject1tipe ContainObject. Ketika Anda melakukan salinan dalam MainObject1, MainObject2dibuat dengan field2berisi nilai yang disalin field1dan ContainObject2mengandung nilai yang disalin ContainObject1. Perhatikan bahwa perubahan apa pun yang dilakukan ContainObject1pada MainObject1tidak akan mencerminkan MainObject2.

artikel bagus


itu bukan salahmu meskipun contoh ini mengacu pada field3yang ketika dalam posisi mencoba dan memahami sesuatu sedalam masalah itu, di mana # 3 dalam contoh itu terjadi ContainObject2 ?
Robb_2015

16

Dalam pemrograman berorientasi objek, tipe menyertakan kumpulan bidang anggota. Bidang-bidang ini dapat disimpan dengan nilai atau referensi (yaitu, penunjuk ke nilai).

Dalam salinan dangkal, instance baru dari tipe dibuat dan nilai-nilai disalin ke instance baru. Pointer referensi juga disalin seperti nilainya. Oleh karena itu, referensi menunjuk ke objek aslinya. Setiap perubahan pada anggota yang disimpan dengan referensi muncul di dokumen asli dan salinan, karena tidak ada salinan yang dibuat dari objek yang direferensikan.

Dalam salinan yang dalam, bidang yang disimpan oleh nilai disalin seperti sebelumnya, tetapi pointer ke objek yang disimpan oleh referensi tidak disalin. Sebagai gantinya, salinan yang dalam dibuat dari objek yang direferensikan, dan sebuah pointer ke objek baru disimpan. Setiap perubahan yang dilakukan pada objek yang direferensikan tidak akan mempengaruhi salinan objek lainnya.


12

'ShallowCopy' menunjuk ke lokasi yang sama dalam memori seperti 'Sumber'. 'DeepCopy' menunjuk ke lokasi yang berbeda dalam memori, tetapi isinya sama.


Ini sedikit menyesatkan. Baik salinan dangkal dan dalam akan menyalin objek ke lokasi baru di memori, dalam juga akan menyalin objek anak sedangkan dangkal hanya akan memiliki objek baru merujuk ke anak-anak yang lama. Sulit dibaca tanpa merujuk ke objek asli.
Bill K

10

Kloning Dangkal:
Definisi: "Salinan dangkal suatu objek menyalin objek 'utama', tetapi tidak menyalin objek dalam." Ketika objek kustom (mis. Karyawan) baru saja primitif, variabel tipe String maka Anda menggunakan Kloning Dangkal.

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

Anda kembali super.clone();dengan metode clone () yang ditimpa dan pekerjaan Anda selesai.

Kloning Dalam :
Definisi: "Berbeda dengan salinan yang dangkal, salinan yang dalam adalah salinan yang sepenuhnya independen dari suatu objek."
Berarti ketika objek Karyawan memegang objek kustom lain:

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

Maka Anda harus menulis kode untuk mengkloning objek 'Alamat' juga dalam metode clone () yang diganti. Jika tidak, objek Alamat tidak akan dikloning dan menyebabkan bug ketika Anda mengubah nilai Alamat di objek Karyawan yang dikloning, yang mencerminkan yang asli juga.


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

Itu bukan contoh yang baik. Salinan dangkal sebagian besar digunakan untuk menyalin objek secara cepat, tanpa menyalin data, tetapi begitu suatu objek perlu memodifikasi data yang dibagikan, salinan yang dalam diambil. Contoh Anda kemungkinan akan membingungkan pemula.
CMircea

ini hanya berfungsi dalam bahasa yang menggunakan pointer untuk mewakili string. Poin yang DHA coba buat adalah bahwa salinan dangkal hanya duplikat pointer ke konten asli yang identik (tunggal), sementara salinan yang dalam mengkloning konten referensi juga. Kedua metode menyalin konten permukaan. Jika bahasa menyimpan string sebagai konten literal permukaan, misalnya di dalam header WAV, contoh ini tidak akan berfungsi. Perhatikan ini mungkin terlalu pilih-pilih untuk sebagian besar masalah kehidupan nyata yang tidak esoteris.
DragonLord

8

Salinan Yang Dalam

Salinan yang dalam menyalin semua bidang, dan membuat salinan dari memori yang dialokasikan secara dinamis ditunjuk oleh bidang tersebut. Salinan dalam terjadi ketika suatu objek disalin bersama dengan objek yang dirujuk.

Salinan dangkal

Salinan dangkal adalah salinan objek yang sedikit bijaksana. Objek baru dibuat yang memiliki salinan tepat dari nilai-nilai di objek asli. Jika salah satu bidang objek referensi ke objek lain, hanya alamat referensi yang disalin yaitu, hanya alamat memori yang disalin.


Tautan itu sayangnya tidak lagi berfungsi - sekarang menunjuk ke sebuah artikel dari Februari 2019 tentang desain web (kecuali penulisnya waskita?).
PhilPhil

7

Salinan Dangkal - Variabel referensi di dalam objek asli dan disalin dangkal memiliki referensi ke objek umum .

Salinan Jauh - Variabel referensi di dalam objek asli dan yang disalin memiliki referensi ke objek yang berbeda .

klon selalu melakukan salinan dangkal.

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

kelas utama mengikuti-

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 di atas akan menjadi-

salah benar benar

false false false

Setiap perubahan yang dilakukan pada objek asli akan mencerminkan objek dangkal tidak dalam objek yang mendalam.

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

OutPut- ViSuaLBaSiC C


7

Saya ingin memberi contoh daripada definisi formal.

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

Kode ini menunjukkan salinan dangkal :

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

Kode ini menunjukkan salinan dalam :

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

Saya mendapatkan1 1 4 4 4 4 4 4
Suresh Prajapati

dalam salinan yang dalam, lakukan copyObject.a = 8 dan kemudian periksa. harap Anda mendapatkan jawaban yang tepat.
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

Dalam Ketentuan Sederhana, Salinan Dangkal mirip dengan Call By Reference dan Deep Copy mirip dengan Call By Value

Dalam Call By Reference, parameter formal dan aktual dari suatu fungsi merujuk ke lokasi memori yang sama dan nilainya.

Dalam Nilai Panggilan Menurut, parameter formal dan aktual dari suatu fungsi merujuk ke lokasi memori yang berbeda tetapi memiliki nilai yang sama.


5

Bayangkan ada dua array yang disebut arr1 dan arr2.

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

5

Salinan dangkal membangun objek majemuk baru dan memasukkan referensi ke dalamnya ke objek asli.

Tidak seperti salinan dangkal, deepcopy membangun objek senyawa baru dan juga menyisipkan salinan objek asli objek senyawa asli.

Mari kita ambil contoh.

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

Kode di atas mencetak SALAH.

Coba lihat caranya.

Objek majemuk asli x=[1,[2]](disebut senyawa karena memiliki objek di dalam objek (Inception))

masukkan deskripsi gambar di sini

seperti yang Anda lihat pada gambar, ada daftar di dalam daftar.

Lalu kami membuat salinan dangkal menggunakan y = copy.copy(x). Apa yang python lakukan di sini adalah, ia akan membuat objek majemuk baru tetapi objek di dalamnya menunjuk ke objek orignal.

masukkan deskripsi gambar di sini

Dalam gambar itu telah membuat salinan baru untuk daftar luar. tetapi daftar bagian dalam tetap sama dengan yang asli.

Sekarang kami membuat deepcopy menggunakan itu z = copy.deepcopy(x). apa yang python lakukan di sini adalah, itu akan membuat objek baru untuk daftar luar maupun daftar dalam. seperti yang ditunjukkan pada gambar di bawah (disorot merah).

masukkan deskripsi gambar di sini

Pada kode akhir dicetak False, karena y dan z bukan objek yang sama.

HTH.


2

Salinan dangkal adalah membuat objek baru dan kemudian menyalin bidang non-statis objek saat ini ke objek baru. Jika bidang adalah tipe nilai -> salinan bidang sedikit demi sedikit dilakukan; untuk tipe referensi -> referensi disalin tetapi objek yang dirujuk tidak; Oleh karena itu objek asli dan klonnya merujuk pada objek yang sama.

Dalam copy adalah menciptakan objek baru dan kemudian menyalin bidang nonstatic dari objek saat ini ke objek baru. Jika bidang adalah tipe nilai -> salinan bidang sedikit demi sedikit dilakukan. Jika bidang adalah tipe referensi -> salinan baru dari objek yang dirujuk dilakukan. Kelas yang akan dikloning harus ditandai sebagai [Serializable].


2

Diambil dari [blog]: http://sickprogrammersarea.blogspot.in/2014/03/technical-interview-questions-on-c_6.html

Salinan mendalam melibatkan penggunaan konten dari satu objek untuk membuat instance lain dari kelas yang sama. Dalam salinan yang dalam, kedua objek mungkin berisi informasi yang sama tetapi objek target akan memiliki buffer dan sumber dayanya sendiri. penghancuran salah satu objek tidak akan mempengaruhi objek yang tersisa. Operator tugas yang kelebihan beban akan membuat salinan objek yang dalam.

Salinan dangkal melibatkan menyalin konten dari satu objek ke instance lain dari kelas yang sama sehingga menciptakan gambar cermin. Karena penyalinan langsung referensi dan petunjuk, kedua objek akan berbagi konten yang sama secara eksternal dari objek lain menjadi tidak dapat diprediksi.

Penjelasan:

Menggunakan copy constructor kami cukup menyalin nilai data anggota dengan anggota. Metode penyalinan ini disebut salinan dangkal. Jika objek adalah kelas sederhana, terdiri dari tipe bawaan dan tidak ada pointer ini akan diterima. Fungsi ini akan menggunakan nilai-nilai dan objek-objek dan perilakunya tidak akan diubah dengan salinan dangkal, hanya alamat pointer yang anggota disalin dan bukan nilai alamat yang menunjuk. Nilai data objek kemudian akan secara tidak sengaja diubah oleh fungsi. Ketika fungsi keluar dari ruang lingkup, salinan objek dengan semua datanya muncul dari tumpukan.

Jika objek memiliki pointer, salinan yang dalam perlu dieksekusi. Dengan salinan mendalam dari suatu objek, memori dialokasikan untuk objek di toko bebas dan elemen yang ditunjuk untuk disalin. Salinan dalam digunakan untuk objek yang dikembalikan dari suatu fungsi.


2

Untuk menambahkan lebih banyak ke jawaban lain,

  • Salinan Dangkal objek melakukan penyalinan dengan nilai untuk properti berbasis tipe nilai, dan salin dengan referensi untuk properti berbasis tipe referensi.
  • Salinan Jauh dari suatu objek melakukan penyalinan dengan nilai untuk properti berbasis tipe nilai, serta menyalin menurut nilai untuk properti berbasis tipe referensi jauh di dalam hierarki (tipe referensi)

2

Salinan dangkal tidak akan membuat referensi baru tetapi salinan yang dalam akan membuat referensi baru.

Berikut adalah program untuk menjelaskan salinan yang dalam dan dangkal.

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

Salinan salinan:

Array adalah kelas, yang artinya adalah tipe referensi sehingga array1 = array2 menghasilkan dua variabel yang mereferensikan array yang sama.

Tapi lihat contoh ini:

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

clone dangkal berarti bahwa hanya memori yang diwakili oleh array yang dikloning disalin.

Jika array berisi objek tipe nilai, nilai disalin ;

jika array berisi tipe referensi, hanya referensi yang disalin - sehingga ada dua array yang anggotanya mereferensikan objek yang sama .

Untuk membuat salinan yang dalam — di mana tipe referensi digandakan, Anda harus mengulang array dan mengkloning setiap elemen secara manual.


Saya tidak tahu tentang bahasa lain, tetapi dalam C # / VB, menyalin dangkal jenis nilai tidak menyalin nilai. Dua array merujuk ke objek yang sama. Tambahkan tombol ke formulir dan tambahkan kode ini untuk melihat: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

Anda benar, saya mengoreksi jawaban saya menjadi lebih tepat, menggunakan klon pada array. Anda sepenuhnya benar bahwa "menyalin dangkal array tipe nilai tidak menyalin nilai", tetapi menggunakan clone on array tidak. Saya sudah mencoba menjelaskan itu, coba saja. Terima kasih
lukaszk

1

Saya jadi mengerti dari baris-baris berikut.

Salinan dangkal menyalin bidang tipe nilai objek (int, float, bool) ke objek target dan tipe referensi objek (string, kelas dll) disalin sebagai referensi di objek target. Dalam target referensi ini jenis akan menunjuk ke lokasi memori objek sumber.

Salinan yang dalam menyalin nilai objek dan tipe referensi ke dalam salinan objek objek yang lengkap yang baru. Ini berarti tipe nilai dan tipe referensi akan dialokasikan ke lokasi memori baru.


0

Menambahkan ke semua definisi di atas, satu salinan dalam yang lebih dan paling sering digunakan, ada di copy constructor (atau overloading assignment oprator) dari kelas.

Salinan dangkal -> adalah saat Anda tidak menyediakan pembuat salinan. Di sini, hanya objek yang disalin tetapi tidak semua anggota kelas disalin.

Salinan dalam -> adalah ketika Anda telah memutuskan untuk mengimplementasikan copy constructor atau tugas yang berlebihan di kelas Anda dan memungkinkan menyalin semua anggota kelas.

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

Copy constructor digunakan untuk menginisialisasi objek baru dengan objek yang dibuat sebelumnya dari kelas yang sama. Secara default kompiler menulis salinan yang dangkal. Salinan dangkal berfungsi dengan baik ketika alokasi memori dinamis tidak terlibat karena ketika alokasi memori dinamis terlibat maka kedua objek akan menunjuk ke lokasi memori yang sama di tumpukan, Oleh karena itu untuk menghapus masalah ini kami menulis salinan yang dalam sehingga kedua objek memiliki salinan atributnya sendiri dalam memori. Untuk membaca detail dengan contoh dan penjelasan lengkap, Anda bisa melihat artikel C ++ konstruktor .

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.