Không, loại trả lại không quan trọng.†
C++ chuẩn không áp đặt bất cứ yêu cầu về kiểu trả về cho phân copy hàm thành viên đặc biệt bạn khai báo chính mình. Nó chỉ cần là một operator=()
có nghĩa là "chính xác một thông số của loại X
, X&
, const X&
, volatile X&
hoặc const volatile X&
". †† Do đó, void operator=(const NonCopyable&);
vẫn là một toán tử gán bản sao (một toán tử do người dùng khai báo, cụ thể).
Vì thực tế bạn đã cung cấp toán tử gán bản sao của riêng mình, nó sẽ làm thay thế thế hệ của toán tử gán bản sao mặc định. Điều này buộc tất cả các cuộc gọi đến nhà điều hành gán bản sao của NonCopyable
để giải quyết cho bạn, gây ra bất kỳ nỗ lực nào để sử dụng toán tử gán bản sao để không biên dịch vì nó được khai báo private
.
class Foo : NonCopyable
{
};
int main()
{
Foo a;
Foo b;
// Compiler complains about `operator=(const NonCopyable&)`
// not accessible or something like that.
a = b;
}
Và vì tôi sẽ không bao giờ có thể thực sự sử dụng nó, điều quan trọng không phải là toán tử gán bản sao chuẩn. Nếu tôi cố gắng sử dụng toán tử gán bản sao nó sẽ dẫn đến lỗi trình biên dịch, đó chính là điều bạn muốn.
† Tất nhiên, điều quan trọng là, nếu nhà điều hành gán bản sao thực sự làm điều gì đó. Nói chung, bạn muốn các nhà khai thác của bạn cư xử giống như những người được xây dựng trong, do đó, trở về một X&
là thực hành tốt khi bạn đang thực sự làm nhiệm vụ.
†† C++ Tiêu chuẩn: đối tượng 12,8 lớp sao chép [class.copy]
Một người dùng tuyên bố bản sao phân công điều hành X::operator=
là một tổ chức phi tĩnh phi mẫu hàm thành viên của lớp X
với chính xác một thông số loại X
, X&
, const X&
, volatile X&
hoặc const volatile X&
.
Cũng lưu ý rằng với C++ 11 bạn có thể làm điều này rõ ràng hơn bằng cách thực hiện 'void operator = (const NonCopyable &) = delete;' –