2012-03-21 30 views
6

tôi đang làm các xét nghiệm sau:Tại sao có bản sao trước khi chuyển nhượng?

#include <iostream> 
#include <vector> 

using namespace std; 
class A 
{ 
private: 
    int i; 
public: 
    A():i(1){cout<<"A constr"<<endl;} 
    A(const A & a):i(a.i){cout<<"A copy"<<endl;} 
    virtual ~A(){cout<<"destruct A"<<endl;} 
    void operator=(const A a){cout<<"A assign"<<endl;} 
}; 


int main() 
{ 
    A o1; 
    A o2; 
    o2=o1; 
} 

Và kết quả là:

A constr 
A constr 
A copy 
A assign 
destruct A 
destruct A 
destruct A 

Dường như "o2 = o1" đã làm một bản sao đầu tiên tiếp theo là một bài tập, và tôi tự hỏi những gì là câu chuyện đằng sau nó. Cảm ơn!

Trả lời

15

Bởi vì bạn vượt qua bởi giá trị vào toán tử gán của bạn:

void operator=(const A a) 

Bạn có thể có nghĩa là để vượt qua bằng cách tham khảo và bạn cũng nên trả về một tham chiếu đến giao để phản đối:

A& operator=(const A& a) { std::cout << "A assign" << std::endl; return *this; } 
4

Bạn dường như thiết lập toán tử gán cho bạn để được triển khai đúng:

T& T::operator= (T value) { 
    value. swap(*this); 
    return *this; 
} 

rgument được truyền qua bản sao cho toán tử assigment và trình biên dịch thực sự cần thiết để làm bản sao này trong thiết lập của bạn. Nếu bạn đã vượt qua một tạm thời các bản sao có thể tránh được:

o2 = A(); 

Như vậy, việc thực hiện trên thực tế có một vài đặc tính thú vị: chức năng

  • nó thúc đẩy đã viết: các nhà xây dựng bản sao hoặc là tạo ra hoặc bằng văn bản, nhưng điều đúng và nếu bạn muốn có một nhiệm vụ, bạn có thể muốn có swap() thành viên cũng như
  • nhiệm vụ là ngoại lệ mạnh an toàn nếu thao tác swap() không được thực hiện. Khi allocators nhập hình ảnh thứ cần phải được thực hiện hơi khác nhau, mặc dù
  • nhiệm vụ cố gắng để tránh hoạt động sao chép thực tế như bản sao trong lập luận đi qua có thể được elided trong một số trường hợp, tức là nội dung chỉ là swap() ed vào vị trí
Các vấn đề liên quan