2010-05-30 33 views
6

Khi toán tử gán quá tải của một lớp trong C++, tham số của nó phải là tham chiếu?Phải có tham số của toán tử gán?

Ví dụ,

class MyClass { 
public: 
... 
MyClass & operator=(const MyClass &rhs); 
... 
} 

Nó có thể được

class MyClass { 
public: 
... 
MyClass & operator=(const MyClass rhs); 
... 
} 

?

Cảm ơn!

Trả lời

9

Tham số của toán tử gán quá tải có thể là bất kỳ kiểu nào và nó có thể được truyền theo tham chiếu hoặc theo giá trị (tốt, nếu loại không thể sao chép được, thì không thể truyền theo giá trị, rõ ràng).

Vì vậy, ví dụ, bạn có thể có một toán tử gán mà phải mất một int như một tham số:

MyClass& operator=(int); 

Toán tử gán bản sao là một trường hợp đặc biệt của một nhà điều hành chuyển nhượng. Đó là bất kỳ toán tử gán nào có cùng loại với lớp, hoặc theo giá trị hoặc theo tham chiếu (tham chiếu có thể là const- hoặc dễ bay hơi).

Nếu bạn không triển khai một cách rõ ràng một số dạng của toán tử gán bản sao, thì trình biên dịch sẽ được khai báo và triển khai ngầm định.

+0

Cảm ơn, James! Đối với toán tử gán bản sao, có loại lớp nào không sao chép được không? Tôi nghĩ rằng tất cả các loại lớp ít nhất có một constructor sao chép mặc định? – Tim

+0

@Tim: Chắc chắn: nếu bạn có một trình tạo bản sao _private_ do người dùng khai báo cho một lớp, thì hàm tạo bản sao sẽ không thể truy cập được (trừ khi bạn đang ở trong một hàm thành viên hoặc bạn của lớp đó) và lớp đó sẽ không được sao chép. Nếu bạn khai báo hàm tạo bản sao nhưng không xác định nó, thì lớp không phải là bản sao có thể xây dựng được (và cố gắng sao chép-xây dựng một cá thể sẽ gây ra các lỗi trình liên kết). Cả hai kỹ thuật này đều được sử dụng (thường là cùng nhau) để gây ra một lớp không được sao chép. –

+0

Cảm ơn! Tôi tự hỏi trong trường hợp nào một lớp học không thể sao chép được là muốn? – Tim

5

Nói chung, tùy thuộc vào quyết định của bạn, không có phải. Biến thể đầu tiên là phổ biến và "canonic" và là ok cho bất kỳ việc thực thi toán tử gán nào.

Khi câu hỏi là tốc độ, tôi nghĩ bạn nên đọc this article về kỹ thuật truyền theo giá trị. Điều này có nghĩa rằng trong một số trường hợp đi qua giá trị sẽ có hiệu quả hơn so với đi qua tham chiếu const.

Ngoài ra, biến thể thứ hai của bạn không cần từ khóa const, bởi vì truyền theo giá trị hoạt động như thể bản sao đã được tạo nên đối tượng gốc chắc chắn sẽ không bị thay đổi.

+0

Cảm ơn Kotti! Khá đọc nó, nhưng không hoàn toàn hiểu tại sao đi qua tham chiếu chậm hơn so với đi qua giá trị? – Tim

+0

Vâng, thường thì không, nhưng điểm của bài viết này là nếu bạn đang làm một bản sao đối tượng ngay sau khi bạn vượt qua nó bằng cách tham chiếu, nó sẽ chậm hơn so với truyền theo giá trị và gán bản sao đó, vì tối ưu hóa trình biên dịch. Điều đó thực sự phức tạp, nhưng không hoàn toàn vô nghĩa ... –

5

C++ Operator Overloading Guidelines đề xuất, toán tử gán sẽ nhận tham chiếu const. Theo trang web, lý do là chúng tôi không muốn thay đổi đối số (từ const), nhưng chỉ là phía bên tay trái của toán tử. Vì vậy, nó tiết kiệm thời gian để vượt qua nó bằng cách tham khảo.

Nó cũng chỉ ra lý do, tại sao cũng tham chiếu được trả về bởi toán tử gán - toán tử chuỗi. Để có được a = (b = 1) hoạt động, cần thiết (b = 1) trả về một tham chiếu có thể được chỉ định (=) đến a.

+0

Liên kết tuyệt vời ... –

3

Bạn có biết bản sao sao chép và hoán đổi để phân định an toàn ngoại lệ không?

MyClass& operator=(const MyClass& rhs) 
{ 
    MyClass copy(rhs); 
    swap(copy); 
    return *this; 
} 

Việc thực hiện có thể được đơn giản hóa (và trong một số trường hợp tăng tốc) thông qua cuộc gọi bằng giá trị:

MyClass& operator=(MyClass copy) 
{ 
    swap(copy); 
    return *this; 
} 
-2

Ok Tôi có vấn đề này và tôi không thể tìm thấy một câu trả lời tốt vì vậy tôi sẽ chia sẻ những gì tôi đã học được.

Bạn có thể vượt qua theo giá trị không có gì sai với điều đó. (như bạn đã trình bày trong câu hỏi của mình.)

Nhưng lý do chúng tôi chuyển tham số bằng tham chiếu const là vì vậy hàm không tạo bản sao thực của giá trị được gọi. giá trị bất cứ nơi nào nó có trong bộ nhớ.

Điều này tiết kiệm thời gian xử lý đặc biệt là nếu một thứ gì đó to lớn có hàng nghìn tên ... Trong trường hợp này, thời gian được lưu sẽ hầu như không có gì.

Và đối với const, đảm bảo người dùng của hàm mà giá trị tham chiếu sẽ không bị thay đổi vì nó có thể được thay đổi vì bạn có quyền truy cập vào vị trí ban đầu trong bộ nhớ vì nó được chuyển theo tham chiếu .. Nếu định nghĩa hàm của bạn thực sự thay đổi giá trị của tham số được gọi trong tham chiếu const, nó sẽ là một lỗi trình biên dịch, nó sẽ không cho phép bạn làm điều đó. bởi vì khi bạn đặt const, bạn đang nói cho trình biên dịch giá trị này không thể thay đổi được.

+0

Cân nhắc tham gia thảo luận như thế này trong phần bình luận. – wizulus

+0

Ý của bạn là gì? Xin lỗi tôi mới, tôi nghĩ những gì tôi viết là một bình luận. – 3366784

+0

Câu hỏi hoặc câu trả lời có số lượng lớn và mũi tên lên và xuống ở bên trái. Có một liên kết bên dưới mỗi liên kết cho biết "' thêm nhận xét' ". Nhấp vào đó sẽ cung cấp cho bạn một hộp văn bản đơn giản để nhập nhận xét, như nhận xét bạn vừa sử dụng. Những gì bạn đã làm trước đó là nhập một câu trả lời ** ở cuối trang trong một phần có tên ** "Câu trả lời của bạn **. Chào mừng bạn đến với StackOverflow :) – wizulus

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