Sự khác biệt giữa một bản sao sâu và một bản sao nông là gì?
Sự khác biệt giữa một bản sao sâu và một bản sao nông là gì?
Câu trả lời:
Các bản sao nông trùng lặp ít nhất có thể. Một bản sao nông của một bộ sưu tập là một bản sao của cấu trúc bộ sưu tập, không phải là các yếu tố. Với một bản sao nông, hai bộ sưu tập hiện chia sẻ các yếu tố riêng lẻ.
Bản sao sâu sắc trùng lặp mọi thứ. Một bản sao sâu của một bộ sưu tập là hai bộ sưu tập với tất cả các yếu tố trong bộ sưu tập ban đầu được nhân đôi.
Bề rộng vs Độ sâu; nghĩ về một cây tham chiếu với đối tượng của bạn là nút gốc.
Nông cạn:
Các biến A và B đề cập đến các vùng nhớ khác nhau, khi B được gán cho A, hai biến tham chiếu đến cùng một vùng nhớ. Những sửa đổi sau này đối với nội dung của một trong hai được phản ánh ngay lập tức trong nội dung của cái khác, khi chúng chia sẻ nội dung.
Sâu:
Các biến A và B đề cập đến các vùng nhớ khác nhau, khi B được gán cho A các giá trị trong vùng nhớ mà điểm A được sao chép vào vùng nhớ mà B trỏ tới. Những sửa đổi sau này đối với nội dung của duy nhất là duy nhất đối với A hoặc B; nội dung không được chia sẻ.
Nói tóm lại, nó phụ thuộc vào những điểm nào. Trong một bản sao nông, đối tượng B trỏ đến vị trí của đối tượng A trong bộ nhớ. Trong bản sao sâu, tất cả mọi thứ trong vị trí bộ nhớ của đối tượng A được sao chép vào vị trí bộ nhớ của đối tượng B.
Bài viết wiki này có một sơ đồ tuyệt vời.
Hãy thử xem xét hình ảnh sau đây
Ví dụ: Object.MemberwiseClone tạo một liên kết sao chép nông
và sử dụng giao diện IClonizable, bạn có thể nhận được bản sao sâu như được mô tả ở đây
Đặc biệt dành cho nhà phát triển iOS:
Nếu B
là một bản sao cạn của A
, sau đó cho dữ liệu nguyên thủy nó giống như B = [A assign];
và cho các đối tượng nó giống như B = [A retain]
;
B và A trỏ đến cùng một vị trí bộ nhớ
Nếu B
là một bản sao sâu của A
, thì nó giống nhưB = [A copy];
B và A trỏ đến các vị trí bộ nhớ khác nhau
Địa chỉ bộ nhớ B giống như của A
B có cùng nội dung với A
Bản sao nông: Sao chép các giá trị thành viên từ đối tượng này sang đối tượng khác.
Deep Copy: Sao chép các giá trị thành viên từ đối tượng này sang đối tượng khác.
Bất kỳ đối tượng con trỏ được sao chép và Deep Copied.
Thí dụ:
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.)
Tôi chưa thấy câu trả lời ngắn gọn, dễ hiểu ở đây - vì vậy tôi sẽ thử.
Với một bản sao nông, bất kỳ đối tượng nào được trỏ đến bởi nguồn cũng được trỏ đến bởi đích (để không có đối tượng được tham chiếu nào được sao chép).
Với một bản sao sâu, bất kỳ đối tượng nào được trỏ đến bởi nguồn được sao chép và bản sao được trỏ đến đích (vì vậy bây giờ sẽ có 2 đối tượng được tham chiếu). Điều này đệ quy xuống cây đối tượng.
Để dễ hiểu, bạn có thể theo dõi bài viết này: https://www.cs.utexas.edu/~scottm/cs307/handouts/deepCopying.htmlm
Bản sao nông:
Sao chép sâu:
{Tưởng tượng hai đối tượng: A và B cùng loại _t (liên quan đến C ++) và bạn đang nghĩ về việc sao chép nông / sâu từ A sang B}
Shallow Copy: Đơn giản chỉ cần tạo một bản sao của tham chiếu đến A thành B. Hãy nghĩ về nó như một bản sao của Địa chỉ A. Vì vậy, địa chỉ của A và B sẽ giống nhau, tức là chúng sẽ được trỏ đến cùng một vị trí bộ nhớ, tức là nội dung dữ liệu.
Sao chép sâu: Đơn giản chỉ cần tạo một bản sao của tất cả các thành viên của A, phân bổ bộ nhớ ở một vị trí khác cho B và sau đó gán các thành viên được sao chép cho B để đạt được bản sao sâu. Theo cách này, nếu A trở thành B không tồn tại thì vẫn còn hiệu lực trong bộ nhớ. Thuật ngữ chính xác để sử dụng sẽ là nhân bản, trong đó bạn biết rằng cả hai đều hoàn toàn giống nhau, nhưng khác nhau (nghĩa là được lưu trữ dưới dạng hai thực thể khác nhau trong không gian bộ nhớ). Bạn cũng có thể cung cấp trình bao bọc nhân bản của mình, nơi bạn có thể quyết định thông qua danh sách bao gồm / loại trừ những thuộc tính sẽ chọn trong khi sao chép sâu. Đây là một thực tế khá phổ biến khi bạn tạo API.
Bạn có thể chọn thực hiện Sao chép nông CHỈ_IF bạn hiểu các cổ phần liên quan. Khi bạn có số lượng lớn các con trỏ để xử lý trong C ++ hoặc C, thực hiện một bản sao nông của một đối tượng là THỰC SỰ là một ý tưởng tồi.
EXAMPLE_OF_DEEP COPY_ Một ví dụ là, khi bạn đang cố gắng xử lý hình ảnh và nhận dạng đối tượng, bạn cần che dấu "Chuyển động không liên quan và lặp lại" ra khỏi khu vực xử lý của mình. Nếu bạn đang sử dụng con trỏ hình ảnh, thì bạn có thể có thông số kỹ thuật để lưu những hình ảnh mặt nạ đó. NGAY BÂY GIỜ ... nếu bạn thực hiện một bản sao nông của hình ảnh, khi các tham chiếu con trỏ bị GỬI từ ngăn xếp, bạn đã mất tham chiếu và bản sao của nó tức là sẽ có lỗi thời gian vi phạm truy cập tại một số điểm. Trong trường hợp này, những gì bạn cần là một bản sao sâu sắc của hình ảnh của bạn bằng cách CLONING nó. Bằng cách này, bạn có thể lấy lại mặt nạ trong trường hợp bạn cần chúng trong tương lai.
EXAMPLE_OF_SHALLOW_COPY Tôi không phải là người cực kỳ am hiểu so với người dùng trong StackOverflow vì vậy hãy thoải mái xóa phần này và đưa ra một ví dụ tốt nếu bạn có thể làm rõ. Nhưng tôi thực sự nghĩ rằng không nên sao chép nông nếu bạn biết rằng chương trình của bạn sẽ chạy trong một khoảng thời gian vô tận, tức là hoạt động "đẩy" liên tục qua ngăn xếp với các lệnh gọi hàm. Nếu bạn đang trình diễn một cái gì đó cho một người nghiệp dư hoặc người mới (ví dụ: công cụ hướng dẫn C / C ++) thì có lẽ không sao. Nhưng nếu bạn đang chạy một ứng dụng như hệ thống giám sát và phát hiện hoặc Hệ thống theo dõi Sonar, bạn không được phép sao chép nông cạn các đối tượng xung quanh vì nó sẽ giết chương trình của bạn sớm hay muộn.
char * Source = "Hello, world.";
char * ShallowCopy = Source;
char * DeepCopy = new char(strlen(Source)+1);
strcpy(DeepCopy,Source);
'ShallowCopy' trỏ đến cùng một vị trí trong bộ nhớ như 'Nguồn'. 'DeepCopy' trỏ đến một vị trí khác trong bộ nhớ, nhưng nội dung giống nhau.
Bản sao nông là gì?
Bản sao nông là một bản sao khôn ngoan của một đối tượng. Một đối tượng mới được tạo có một bản sao chính xác của các giá trị trong đối tượng ban đầu. Nếu bất kỳ trường nào của đối tượng là tham chiếu đến các đối tượng khác, chỉ có các địa chỉ tham chiếu được sao chép tức là chỉ có địa chỉ bộ nhớ được sao chép.
Trong hình này, các MainObject1
trường field1
có kiểu int và ContainObject1
kiểu ContainObject
. Khi bạn thực hiện một bản sao nông MainObject1
, MainObject2
được tạo bằng cách field2
chứa giá trị được sao chép của field1
và vẫn trỏ đến ContainObject1
chính nó. Lưu ý rằng vì field1
thuộc loại nguyên thủy, giá trị của nó được sao chép vào field2
nhưng vì ContainedObject1
là một đối tượng nên MainObject2
vẫn trỏ đến ContainObject1
. Vì vậy, bất kỳ thay đổi được thực hiện ContainObject1
trong MainObject1
sẽ được phản ánh trong MainObject2
.
Bây giờ nếu đây là bản sao nông, hãy xem bản sao sâu?
Bản sao sâu là gì?
Một bản sao sâu sao chép tất cả các trường và tạo các bản sao của bộ nhớ được phân bổ động được chỉ ra bởi các trường. Một bản sao sâu xảy ra khi một đối tượng được sao chép cùng với các đối tượng mà nó đề cập đến.
Trong hình này, MainObject1 có các trường field1
kiểu int và ContainObject1
kiểu ContainObject
. Khi bạn thực hiện một bản sao sâu MainObject1
, MainObject2
được tạo bằng cách field2
chứa giá trị được sao chép của field1
và ContainObject2
chứa giá trị được sao chép của ContainObject1
. Lưu ý bất kỳ thay đổi được thực hiện ContainObject1
trong MainObject1
sẽ không phản ánh trong MainObject2
.
field3
mà khi cố gắng hiểu một vấn đề sâu sắc như vấn đề đó, thì số 3 trong ví dụ đó đang diễn ra ở ContainObject2
đâu?
Trong lập trình hướng đối tượng, một kiểu bao gồm một tập hợp các trường thành viên. Các trường này có thể được lưu trữ theo giá trị hoặc theo tham chiếu (nghĩa là một con trỏ tới một giá trị).
Trong một bản sao nông, một thể hiện mới của loại được tạo và các giá trị được sao chép vào thể hiện mới. Các con trỏ tham chiếu cũng được sao chép giống như các giá trị. Do đó, các tham chiếu được trỏ đến các đối tượng ban đầu. Mọi thay đổi đối với các thành viên được lưu trữ bằng tham chiếu sẽ xuất hiện trong cả bản gốc và bản sao, vì không có bản sao nào được tạo từ đối tượng được tham chiếu.
Trong một bản sao sâu, các trường được lưu trữ theo giá trị được sao chép như trước, nhưng các con trỏ tới các đối tượng được lưu trữ bởi tham chiếu không được sao chép. Thay vào đó, một bản sao sâu được tạo từ đối tượng được tham chiếu và một con trỏ tới đối tượng mới được lưu trữ. Mọi thay đổi được thực hiện cho các đối tượng được tham chiếu đó sẽ không ảnh hưởng đến các bản sao khác của đối tượng.
'ShallowCopy' trỏ đến cùng một vị trí trong bộ nhớ như 'Nguồn'. 'DeepCopy' trỏ đến một vị trí khác trong bộ nhớ, nhưng nội dung giống nhau.
Nhân bản nông:
Định nghĩa: "Một bản sao nông của một đối tượng sao chép đối tượng 'chính', nhưng không sao chép các đối tượng bên trong." Khi một đối tượng tùy chỉnh (ví dụ: Nhân viên) chỉ nguyên thủy, biến kiểu chuỗi thì bạn sử dụng Nhân bản nông.
Employee e = new Employee(2, "john cena");
Employee e2=e.clone();
Bạn quay lại super.clone();
trong phương thức clone () bị ghi đè và công việc của bạn đã kết thúc.
Bản sao sâu :
Định nghĩa: "Không giống như bản sao nông, bản sao sâu là bản sao hoàn toàn độc lập của một đối tượng."
Có nghĩa là khi một đối tượng Nhân viên giữ một đối tượng tùy chỉnh khác:
Employee e = new Employee(2, "john cena", new Address(12, "West Newbury", "Massachusetts");
Sau đó, bạn phải viết mã để sao chép đối tượng 'Địa chỉ' cũng như trong phương thức clone () bị ghi đè. Mặt khác, đối tượng Địa chỉ sẽ không được sao chép và nó gây ra lỗi khi bạn thay đổi giá trị của Địa chỉ trong đối tượng Nhân viên nhân bản, điều này cũng phản ánh đối tượng gốc.
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
Sao chép sâu
Một bản sao sâu sao chép tất cả các trường và tạo các bản sao của bộ nhớ được phân bổ động được chỉ ra bởi các trường. Một bản sao sâu xảy ra khi một đối tượng được sao chép cùng với các đối tượng mà nó đề cập đến.
Bản sao nông
Bản sao nông là một bản sao khôn ngoan của một đối tượng. Một đối tượng mới được tạo có một bản sao chính xác của các giá trị trong đối tượng ban đầu. Nếu bất kỳ trường nào của đối tượng là tham chiếu đến các đối tượng khác, thì chỉ các địa chỉ tham chiếu được sao chép tức là chỉ có địa chỉ bộ nhớ được sao chép.
Shallow Copy - Biến tham chiếu bên trong các đối tượng gốc và sao chép nông có tham chiếu đến đối tượng chung .
Deep Copy - Biến tham chiếu bên trong các đối tượng gốc và sao chép sâu có tham chiếu đến các đối tượng khác nhau .
clone luôn luôn sao chép nông.
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();
}
}
lớp chính đang theo-
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 ở trên sẽ-
sai đúng đúng
sai sai sai
Bất kỳ thay đổi nào được thực hiện trong đối tượng gốc sẽ phản ánh trong đối tượng nông không ở đối tượng sâu.
list.get(0).name="ViSuaLBaSiC";
System.out.println(shallow.get(0).getName()+" "+deep.get(0).getName());
OutPut- ViSuaLBaSiC C
Tôi muốn đưa ra ví dụ hơn là định nghĩa chính thức.
var originalObject = {
a : 1,
b : 2,
c : 3,
};
Mã này hiển thị một bản sao nông :
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
Mã này hiển thị một bản sao sâu :
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
Trong Điều khoản đơn giản, Bản sao nông tương tự như Gọi theo tham chiếu và Bản sao sâu tương tự như Gọi theo giá trị
Trong cuộc gọi theo tham chiếu, cả hai tham số chính thức và thực tế của một hàm đều đề cập đến cùng một vị trí bộ nhớ và giá trị.
Trong Call By Value, cả hai tham số chính thức và thực tế của một hàm đều đề cập đến vị trí bộ nhớ khác nhau nhưng có cùng giá trị.
Hãy tưởng tượng có hai mảng được gọi là Array1 và Array2.
arr1 = arr2; //shallow copy
arr1 = arr2.clone(); //deep copy
Một bản sao nông xây dựng một đối tượng ghép mới và chèn các tham chiếu của nó vào đối tượng ban đầu.
Không giống như bản sao nông, deepcopy xây dựng đối tượng ghép mới và cũng chèn các bản sao của các đối tượng gốc của đối tượng ghép ban đầu.
Hãy lấy một ví dụ.
import copy
x =[1,[2]]
y=copy.copy(x)
z= copy.deepcopy(x)
print(y is z)
Trên mã in FALSE.
Để xem thế nào.
Đối tượng ghép gốc x=[1,[2]]
(được gọi là hợp chất vì nó có đối tượng bên trong đối tượng (Inception))
như bạn có thể thấy trong hình, có một danh sách bên trong danh sách.
Sau đó, chúng tôi tạo ra một bản sao nông của nó bằng cách sử dụng y = copy.copy(x)
. Những gì python làm ở đây là, nó sẽ tạo ra một đối tượng ghép mới nhưng các đối tượng bên trong chúng đang chỉ vào các đối tượng gốc.
Trong hình ảnh, nó đã tạo ra một bản sao mới cho danh sách bên ngoài. nhưng danh sách bên trong vẫn giống như bản gốc.
Bây giờ chúng tôi tạo ra bản đồ sâu của nó bằng cách sử dụng z = copy.deepcopy(x)
. Những gì python làm ở đây là, nó sẽ tạo đối tượng mới cho danh sách bên ngoài cũng như danh sách bên trong. như thể hiện trong hình ảnh dưới đây (màu đỏ nổi bật).
Ở phần cuối mã in False
, vì y và z không phải là cùng một đối tượng.
HTH.
Sao chép nông là tạo một đối tượng mới và sau đó sao chép các trường không tĩnh của đối tượng hiện tại sang đối tượng mới. Nếu một trường là một loại giá trị -> một bản sao từng bit của trường được thực hiện; đối với loại tham chiếu -> tham chiếu được sao chép nhưng đối tượng được tham chiếu thì không; do đó, đối tượng ban đầu và bản sao của nó tham chiếu đến cùng một đối tượng.
Sao chép sâu đang tạo một đối tượng mới và sau đó sao chép các trường không thuộc tính của đối tượng hiện tại sang đối tượng mới. Nếu một trường là một loại giá trị -> một bản sao từng bit của trường được thực hiện. Nếu một trường là một kiểu tham chiếu -> một bản sao mới của đối tượng được tham chiếu được thực hiện. Các lớp được nhân bản phải được gắn cờ là [Nối tiếp].
Lấy từ [blog]: http://sickprogrammersarea.blogspot.in/2014/03/technical-interview-questions-on-c_6.html
Sao chép sâu liên quan đến việc sử dụng nội dung của một đối tượng để tạo một thể hiện khác của cùng một lớp. Trong một bản sao sâu, hai đối tượng có thể chứa thông tin ht giống nhau nhưng đối tượng đích sẽ có bộ đệm và tài nguyên riêng. sự phá hủy của một trong hai đối tượng sẽ không ảnh hưởng đến đối tượng còn lại. Toán tử gán quá tải sẽ tạo ra một bản sao sâu của các đối tượng.
Bản sao nông bao gồm sao chép nội dung của một đối tượng vào một thể hiện khác của cùng một lớp, do đó tạo ra một hình ảnh phản chiếu. Do sao chép thẳng các tham chiếu và con trỏ, hai đối tượng sẽ chia sẻ cùng một nội dung được chứa bên ngoài của đối tượng khác để không thể đoán trước.
Giải trình:
Sử dụng một hàm tạo sao chép, chúng ta chỉ cần sao chép các giá trị dữ liệu theo thành viên. Phương pháp sao chép này được gọi là bản sao nông. Nếu đối tượng là một lớp đơn giản, bao gồm các kiểu được xây dựng và không có con trỏ thì điều này có thể được chấp nhận. Hàm này sẽ sử dụng các giá trị và các đối tượng và hành vi của nó sẽ không bị thay đổi với một bản sao nông, chỉ các địa chỉ của các con trỏ là thành viên được sao chép và không phải là giá trị mà địa chỉ đang trỏ tới. Các giá trị dữ liệu của đối tượng sau đó sẽ vô tình bị thay đổi bởi hàm. Khi hàm vượt quá phạm vi, bản sao của đối tượng với tất cả dữ liệu của nó sẽ được bật ra khỏi ngăn xếp.
Nếu đối tượng có bất kỳ con trỏ nào, một bản sao sâu cần được thực thi. Với bản sao sâu của một đối tượng, bộ nhớ được phân bổ cho đối tượng trong cửa hàng miễn phí và các yếu tố được trỏ đến được sao chép. Một bản sao sâu được sử dụng cho các đối tượng được trả về từ một hàm.
Để thêm nhiều hơn vào các câu trả lời khác,
Bản sao nông sẽ không tạo tài liệu tham khảo mới nhưng bản sao sâu sẽ tạo tài liệu tham khảo mới.
Đây là chương trình để giải thích các bản sao sâu và nông.
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 + "]";
}
}
Sao chép ararys:
Mảng là một lớp, có nghĩa là nó là kiểu tham chiếu nên mảng1 = mảng2 dẫn đến hai biến tham chiếu cùng một mảng.
Nhưng hãy nhìn vào ví dụ này:
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 nông có nghĩa là chỉ bộ nhớ được đại diện bởi mảng nhân bản được sao chép.
Nếu mảng chứa các đối tượng kiểu giá trị, các giá trị được sao chép ;
nếu mảng chứa kiểu tham chiếu, chỉ các tham chiếu được sao chép - do đó, có hai mảng có thành viên tham chiếu cùng một đối tượng .
Để tạo một bản sao sâu, trong đó kiểu tham chiếu được sao chép, bạn phải lặp qua mảng và sao chép từng phần tử theo cách thủ công.
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]); }
Tôi đã hiểu từ những dòng sau.
Shallow sao chép các trường loại giá trị đối tượng (int, float, bool) vào các loại tham chiếu của đối tượng và đối tượng (chuỗi, lớp, v.v.) được sao chép dưới dạng tham chiếu trong đối tượng đích. Trong mục đích này, các kiểu tham chiếu sẽ được trỏ đến vị trí bộ nhớ của đối tượng nguồn.
Bản sao sâu sao chép các giá trị và loại tham chiếu của một đối tượng thành một bản sao hoàn toàn mới của các đối tượng đích. Điều này có nghĩa là cả loại giá trị và loại tham chiếu sẽ được phân bổ một vị trí bộ nhớ mới.
Thêm vào tất cả các định nghĩa ở trên, một bản sao sâu hơn và được sử dụng phổ biến nhất, nằm trong hàm tạo sao chép (hoặc nạp chồng công cụ chuyển nhượng) của lớp.
Bản sao nông -> là khi bạn không cung cấp hàm tạo sao chép. Ở đây, chỉ có đối tượng được sao chép nhưng không phải tất cả các thành viên của lớp được sao chép.
Sao chép sâu -> là khi bạn đã quyết định triển khai hàm tạo sao chép hoặc gán quá tải trong lớp của mình và cho phép sao chép tất cả các thành viên của lớp.
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
}
Hàm tạo sao chép được sử dụng để khởi tạo đối tượng mới với đối tượng được tạo trước đó của cùng một lớp. Theo mặc định trình biên dịch đã viết một bản sao nông. Sao chép nông hoạt động tốt khi không phân bổ bộ nhớ động vì khi tham gia cấp phát bộ nhớ động thì cả hai đối tượng sẽ hướng về cùng một vị trí bộ nhớ trong một đống, do đó để loại bỏ vấn đề này, chúng tôi đã viết bản sao sâu để cả hai đối tượng có bản sao thuộc tính riêng trong một ký ức Để đọc chi tiết với các ví dụ và giải thích đầy đủ, bạn có thể xem các nhà xây dựng bài viết C ++ .