2012-01-30 44 views
15

Tôi đang thực hiện một số sửa đổi C++ của mình và tôi đang xử lý quá tải toán tử vào phút, cụ thể là toán tử "=" (gán). Tôi đang tìm kiếm trực tuyến và bắt gặp nhiều chủ đề thảo luận về nó. Trong ghi chép của tôi, tôi có tất cả các ví dụ tôi đưa xuống như một cái gì đó giống nhưTại sao toán tử gán phải trả về một tham chiếu đến đối tượng?

class Foo 
{ 
    public: 
     int x; 
     int y; 
     void operator=(const Foo&); 
}; 
void Foo::operator=(const Foo &rhs) 
{ 
    x = rhs.x; 
    y = rhs.y; 
} 

Trong tất cả các tài liệu tham khảo tôi thấy trên mạng, tôi nhận thấy rằng các nhà điều hành trả về một tham chiếu đến đối tượng nguồn. Tại sao cách chính xác để trả về một tham chiếu đến đối tượng trái ngược với không có gì cả?

+0

Cách đúng là bất cứ cách nào thực hiện các ngữ nghĩa bạn muốn; cách _idiomatic_ chắc chắn trả về 'T &' ('Foo &' trong ví dụ của bạn). – ildjarn

+0

@MooingDuck, tôi đoán tôi đã nói sai câu hỏi. Tôi đã đi trên giả định rằng các ghi chú của tôi là sai, nhưng muốn biết tại sao nhiều hơn là chính xác. – maccard

+1

có thể trùng lặp của [toán tử gán trả về một tham chiếu đến * điều này trong C++] (http://stackoverflow.com/questions/5669813/assignment-operator-return-a-reference-to-this-in-c); cũng [Trả lại * điều này với một toán tử gán] (http://stackoverflow.com/questions/3248469/returning-this-with-an-assignment-operator) –

Trả lời

17

Biểu mẫu thông thường trả về tham chiếu đến đối tượng đích để cho phép chuỗi chỉ định. Nếu không, bạn sẽ không thể thực hiện:

Foo a, b, c; 
// ... 
a = b = c; 

Tuy nhiên, hãy ghi nhớ rằng nhận đúng toán tử điều hành is tougher than it might seem.

+0

Không bao giờ biết về phần Sao chép và hoán đổi. Tôi đã luôn luôn chỉ cần kiểm tra cho tự gán, giá trị được giao, và trả lại void, tôi đoán có nhiều điều này hơn tôi đã mong đợi. Chấp nhận câu trả lời của bạn để chỉ ra Bản sao & Hoán đổi Cảm ơn bạn đã trả lời. – maccard

13

loại Sự trở lại không quan trọng khi bạn chỉ cần thực hiện một nhiệm vụ duy nhất trong một tuyên bố như thế này:

x = y; 

Nó bắt đầu quan trọng khi bạn làm điều này:

if ((x = y)) { 

. .. và thực sự quan trọng khi bạn thực hiện việc này:

x = y = z; 

Đó là lý do bạn trả lại đối tượng hiện tại: cho tất cả nợ chuỗi chỉ định với sự kết hợp chính xác. Đó là một thực hành chung tốt.

+0

Tôi không hiểu tại sao bạn nói "nó bắt đầu quan trọng". Hoặc là nó quan trọng hay không. Bạn có thể vui lòng xây dựng? – balajeerc

+3

@balajeerc: "Nó bắt đầu có vấn đề" trong tiếng Anh được đọc có nghĩa là "nó quan trọng trong tình huống sau nhưng không phải là trước đây". Nói cách khác, "khi thay đổi từ tình huống A sang B, tầm quan trọng ('vật chất') đi từ 0 đến không đồng đẳng". Trong chuyển nhượng thẳng sự trở lại không quan trọng. Bên trong một điều kiện nó quan trọng nếu điều bạn trả về là đúng hay sai, nhưng không chính xác đối tượng đó là gì. Trong trường hợp bài tập bị xiềng xích, bạn thực sự muốn trở lại làm đối tượng hiện tại vì kết quả sẽ ngược lại nếu không. – Borealid

8

toán tử gán của bạn nên luôn luôn làm những ba điều:

  1. Hãy const tham chiếu đầu vào (const MyClass &rhs) như phía bên tay phải của nhiệm vụ. Lý do cho điều này nên rõ ràng, vì chúng ta không muốn vô tình thay đổi giá trị đó; chúng tôi chỉ muốn thay đổi những gì ở phía bên tay trái.

  2. Luôn trả về tham chiếu đến mặt bên trái mới được sửa đổi, return *this. Điều này là để cho phép chuỗi nhà điều hành, ví dụ: a = b = c;.

  3. Luôn kiểm tra tự gán (this == &rhs). Điều này đặc biệt quan trọng khi lớp của bạn thực hiện phân bổ bộ nhớ riêng.

    MyClass& MyClass::operator=(const MyClass &rhs) { 
        // Check for self-assignment! 
        if (this == &rhs) // Same object? 
         return *this; // Yes, so skip assignment, and just return *this. 
    
        ... // Deallocate, allocate new space, copy values, etc... 
    
        return *this; //Return self 
    } 
    
+1

Kiểm tra việc tự gán là một giải pháp ngây thơ, đúng là giải pháp sao chép và trao đổi. –

+0

Cảm ơn bạn đã phản hồi, nhưng tôi chỉ cố gắng tạo một ví dụ đơn giản bằng cách bỏ qua kiểm tra tự gán. Tôi hiểu tất cả mọi thứ thanh trở lại một tài liệu tham khảo. – maccard

+0

@MatteoItalia Sao chép và hoán đổi có thể tốn kém. Ví dụ, gán một vector lớn cho một véc tơ khác không thể tái sử dụng bộ nhớ của đích nếu sao chép và hoán đổi được sử dụng. –

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