2012-10-07 39 views
5

Tiếp tục từ previous question Tôi muốn hỏi tại sao "người bạn" dạng bổ sung trong một C++ hành ghi đè được ưa thíchGhi đè toán tử C++ - tại sao bạn bè lại ưa thích nó?

Để tóm tắt:

cho ghi đè điều hành Ngoài ra có hai cách để làm điều đó :

int operator+(Object& e); 
friend int operator+(Object& left, Object& right); 

tại sao biểu mẫu thứ hai (bạn) được ưa thích hơn? Các lợi thế là gì?

+1

Có lẽ tốt hơn để trích dẫn các bit có liên quan từ câu hỏi cuối cùng, vì vậy mọi người không phải nhấp qua nó (và cũng có thể trong trường hợp câu hỏi biến mất) – nneonneo

Trả lời

5

Phiên bản không phải thành viên (bạn bè hoặc người khác) được ưu tiên vì nó có thể hỗ trợ chuyển đổi ngầm ở cả bên trái và bên phải của toán tử.

Cho một loại đó là mặc nhiên chuyển đổi cho đối tượng:

struct Widget 
{ 
    operator Object() const; 
}; 

Chỉ có phiên bản không phải thành viên có thể được gọi nếu một thể hiện của Widget xuất hiện ở bên trái:

Widget w; 
Object o; 

o + w; // can call Object::operator+(Object &) since left-hand side is Object 
w + o; // can only call operator+(Object &, Object &) 

Để trả lời nhận xét của bạn:

Bằng cách xác định chuyển đổi op erator trong Widget, chúng tôi thông báo cho trình biên dịch rằng các phiên bản Widget có thể được tự động chuyển đổi thành các phiên bản Object.

Widget w; 
Object o = w; // conversion 

Trong biểu o + w, trình biên dịch gọi Object::operator+(Object &) với một cuộc tranh cãi được tạo ra bằng cách chuyển đổi w một Object. Vì vậy, kết quả là giống như viết o + w.operator Object().

Nhưng trong biểu thức w + o, trình biên dịch tìm kiếm Widget::operator+ (không tồn tại) hoặc không phải là thành viên operator+(Widget, Object). Sau này có thể được gọi bằng cách chuyển đổi w thành một số Object như trên.

+0

Tôi không hoàn toàn hiểu mã widget/đối tượng struct, bạn có thể vui lòng cung cấp một ví dụ đơn giản và cực kỳ ngắn không? –

2

Quy tắc không phổ biến: phiên bản friend được ưu tiên khi bạn triển khai hoạt động đối xứng lôgic có hai đối số cùng loại, chẳng hạn như trường hợp bài đăng của bạn thể hiện.

Việc triển khai này nhấn mạnh thực tế rằng thao tác thực sự đối xứng: không phải là 'Đối tượng này' để tự thêm Object e vào chính nó - thay vào đó là bổ sung lhsrhs.

Trong những tình huống khi hoạt động là không đối xứng - ví dụ, khi bạn thêm một int một iterator, bạn nên chọn cách đầu tiên của các nhà khai thác triển khai, cụ thể là

Object& operator+(int& offset); 
Các vấn đề liên quan