std::swap
được triển khai bằng cách thực hiện xây dựng di chuyển, sau đó là hai thao tác gán di chuyển. Vì vậy, trừ khi bạn thực hiện hoạt động swap
của riêng bạn thay thế cho thao tác được cung cấp tiêu chuẩn, mã của bạn như được trình bày là một vòng lặp vô hạn.
Vì vậy, bạn có thể triển khai phương pháp 2 operator=
hoặc triển khai một phương thức operator=
và một phương pháp swap
. Xét về số lượng hàm được gọi, nó hoàn toàn giống hệt nhau.
Ngoài ra, phiên bản operator=
của bạn đôi khi kém hiệu quả hơn. Trừ khi việc xây dựng các tham số được elided, xây dựng sẽ được thực hiện thông qua một bản sao/di chuyển từ giá trị của người gọi. Sau đây là 1 công trình xây dựng và 2 bài tập chuyển động (hoặc bất kỳ bài tập nào của bạn swap
). Trong khi đó, quá tải operator=
có thể hoạt động trực tiếp với tham chiếu được đưa ra.
Và điều này giả định rằng bạn không thể viết phiên bản tối ưu của bài tập thực tế. Xem xét sao chép chỉ định một vector
cho người khác. Nếu đích đến vector
có đủ bộ nhớ để giữ kích thước của vectơ nguồn ... bạn không cần phân bổ. Trong khi nếu bạn sao chép xây dựng, bạn phải phân bổ bộ nhớ. Chỉ để sau đó giải phóng dung lượng mà bạn có thể đã sử dụng.
Ngay cả trong trường hợp tốt nhất, bản sao/di chuyển của bạn & trao đổi sẽ không còn nhiều hơn hiệu quả hơn sử dụng giá trị. Sau khi tất cả, bạn sẽ có một tham chiếu đến tham số; std::swap
không hoạt động trên các giá trị. Vì vậy, bất cứ điều gì hiệu quả bạn nghĩ sẽ bị mất bằng cách sử dụng tài liệu tham khảo sẽ bị mất một trong hai cách.
Những lập luận về nguyên tắc có lợi cho sao chép/di chuyển & hoán đổi là:
Giảm sự trùng lặp mã. Điều này chỉ thuận lợi nếu việc bạn thực hiện các thao tác gán bản sao/di chuyển sẽ ít nhiều giống với việc xây dựng sao chép/di chuyển. Điều này không đúng với nhiều loại; như đã nêu trước đây, vector
có thể tối ưu hóa chính nó một chút bằng cách sử dụng bộ nhớ hiện có nếu có thể. Thật vậy, nhiều container có thể (đặc biệt là các thùng chứa chuỗi).
Cung cấp bảo đảm ngoại lệ mạnh mẽ với nỗ lực tối thiểu. Giả sử constructor di chuyển của bạn là noexcept.
Cá nhân, tôi muốn tránh hoàn toàn tình huống này. Tôi thích cho phép trình biên dịch tạo ra tất cả các chức năng thành viên đặc biệt của tôi. Và nếu một loại hoàn toàn cần tôi viết những hàm thành viên đặc biệt này, thì loại này sẽ càng nhỏ càng tốt. Đó là, nó là mục đích duy nhất sẽ được quản lý bất cứ điều gì nó là yêu cầu hoạt động này.
Bằng cách đó, tôi không phải lo lắng về điều đó. Tỷ lệ các lớp học của sư tử không cần bất kỳ chức năng nào trong số này để được xác định rõ ràng.
Điều này đã bị đánh đến chết hàng triệu lần - ví dụ: http://stackoverflow.com/a/24018053/2756719 –
@ T.C. Tôi bối rối. Bạn có thể xây dựng thêm về nó? Có thể đăng câu trả lời? – Lingxi
Tôi nghĩ nó được đề cập khá tốt trong [thảo luận này về thành ngữ sao chép và hoán đổi] (http://stackoverflow.com/a/3279550/27678) – AndyG