2012-04-02 41 views
5

Ai đó có thể giải thích cho tôi sự khác biệt giữa sao chép và chuyển nhượng không?sao chép và chuyển nhượng

SomeClass a; 
SomeClass b = a; // assignment 
SomeClass c(a); // assignment 
b = c; // copying 

nhưng sự khác biệt là gì, tại sao có hai cấu trúc khác nhau trong ngôn ngữ?

+1

gì bạn gọi là "chuyển nhượng" là thực sự gọi là "khởi tạo", và những gì bạn gọi là "sao chép" được gọi là "chuyển nhượng". – Philipp

+4

'SomeClass a();' - Đó là một khai báo hàm. –

+0

Có thể trùng lặp: http://stackoverflow.com/questions/5368258/the-copy-constructor-and-assignment-operator –

Trả lời

1

Sao chép để khởi tạo đối tượng mới bằng cách sao chép nội dung của đối tượng hiện có, gán cho ghi đè đối tượng hiện có với nội dung của các đối tượng khác - hai đối tượng này rất khác nhau. Đặc biệt, đây

SomeClass a; 
SomeClass b = a; 

bản sao khởi - bạn đang sao chép a để tạo ra một SomeClass mới gọi là b sử dụng cú pháp của hình thức

T x = y; 

này có tác dụng cách gọi SomeClass 's sao chép constructor (giả sử có một và nó có thể truy cập). Trình tạo bản sao mặc định do trình biên dịch tạo ra sẽ thực hiện sao chép thành viên a; bạn có thể thay thế nó bằng chính bạn nếu cần, ví dụ:

SomeClass(const SomeClass& rhs) 
: x(rhs.x) 
{} 

(Lưu ý rằng đây là một ví dụ rất nhàm chán, vì nó chỉ làm những gì các ngầm định copy constructor sức.)

Di chuyển trên, đây

SomeClass c(a); 

trực tiếp khởi bằng cách sử dụng hàm tạo bản sao. Nói chung sẽ có tác dụng tương tự như trên, nhưng điều này là đáng đọc:

http://www.gotw.ca/gotw/036.htm

Ngoài ra, xem ở đây:

http://www.gotw.ca/gotw/001.htm

trường hợp cuối cùng của bạn, cụ thể là

b = c; 

là bài tập. Các ngữ nghĩa của điều này thường phải ghi đè lên b với nội dung của c (mặc dù một số thứ, chẳng hạn như std::auto_ptr, có ngữ nghĩa phân bổ lạ, vì vậy hãy chú ý). Để thực hiện toán tử gán của riêng bạn, bạn viết một cái gì đó như thế này (lưu ý rằng đây là một ví dụ rất nhàm chán, vì nó chỉ làm những gì toán tử gán ngầm định có thể):

SomeClass& operator=(const SomeClass& rhs) 
{ 
    x = rhs.x; 
    return *this; 
} 

Trên thực tế, tuy nhiên, bạn phải hãy cẩn thận về sự an toàn ngoại lệ trong các tình huống như thế này, dẫn đến những thứ như thành ngữ sao chép và hoán đổi phổ biến để thực hiện các toán tử gán. Xem ở đây:

http://en.wikibooks.org/wiki/More_C++_Idioms/Copy-and-swap

2

Đây là khởi tạo (nhưng nó gọi các nhà xây dựng bản sao):

SomeClass b = a; 

Vì vậy, là thế này:

SomeClass c(a); 

Đây là bài tập:

b = c; 

Oh, và isn't an initialization này :

SomeClass a(); 
+0

sự khác biệt - công việc chuyển nhượng trên đối tượng 'đã được tạo' trong khi sao chép vào đối tượng mới được xây dựng mà trước đó không tồn tại. –

1

Khởi tạo khởi tạo đối tượng chưa được khởi tạo trước đó. Các nhiệm vụ, mặt khác, ghi đè một đối tượng đã được khởi tạo và có thể phải hủy bỏ trạng thái hiện tại. Đây là những hoạt động khác nhau; trong khi chúng thường có cùng kết quả cho đối tượng trên LHS, chúng không tương đương về mặt ngữ nghĩa.

3

Việc khởi tạo chỉ xảy ra một lần khi đối tượng được tạo. Nếu bằng cách sao chép bạn có nghĩa là gọi các nhà xây dựng bản sao, hơn sao chép là một hình thức khởi tạo. Nhiệm vụ có thể xảy ra bất kỳ số lần nào.

Bây giờ, trên ví dụ của bạn, tất cả những sai:

SomeClass a(); 

này tuyên bố một phương pháp gọi là a mà mất không tham số và trả về một đối tượng SomeClass.

SomeClass b = a; // actually copy constructor & initialization of b 
SomeClass c(a); // same 

Nếu a là một đối tượng SomeClass, hai sẽ được khởi tạo, và nó gọi constructor sao chép - SomeClass::SomeClass(const SomeClass&). Chúng tương đương nhau.

b = c; // assignment 

Nếu c là một đối tượng SomeClass, này là chuyển nhượng. Nó gọi là SomeClass::operator =(const SomeClass&).

Các vấn đề liên quan