2015-04-06 36 views
6

Tôi đã kiểm tra quá tải nhà điều hành trong C + + và đi qua một cái gì đó tôi đã không mong đợi và có một số nghi ngờ về nó.constructor sao chép rõ ràng biên dịch lỗi

constructor sao chép của tôi là tuyên bố và thực hiện như là

explicit Vector(const Vector& v); 

Vector::Vector(const Vector& v) : 
_x(v._x), _y(v._y), _z(v._z) {} 

sau đó tôi đang quá tải toán tử gán phức hợp

Vector Vector::operator+(const Vector& v) const 
{ 
    Vector tmp(*this); 
    tmp += v; 
    return tmp; 
} 

Vector Vector::operator-(const Vector& v) const 
{ 
    Vector tmp(*this); 
    tmp -= v; 
    return tmp; 
} 

Tuy nhiên, trong báo cáo return tôi đã nhận một lỗi nói no matching constructor for initialization of 'Vector'.

Vì điều duy nhất tôi thêm vào nhà xây dựng của mình là từ khóa explicit, tôi đã xóa nó và mã biên dịch tốt, tại sao?

Tôi cũng đã kiểm tra công cụ mới từ C++ 11 và xảy ra mà tôi có thể tuyên bố constructor của tôi giống như một chuyển động-constructor

explicit Vector(const Vector&& v); 

và mã biên dịch tốt. Nếu tôi làm điều đó, tôi có phải có cả hai bản sao và di chuyển các nhà thầu không?

explicit Vector(const Vector& v); 
explicit Vector(const Vector&& v); 

hoặc chỉ có trình khởi tạo di chuyển sẽ hoạt động tốt? Nếu tôi muốn gắn bó với C++ 11, phương pháp tiếp cận chính xác là gì?

+0

bản sao có thể có của [Trình tạo bản sao rõ ràng] (http://stackoverflow.com/questions/11480545/explicit-copy-constructor) – Predelnik

+0

Nhiều khả năng '+ =' và '- =' đang tạo bản sao ẩn gây ra lỗi. – NathanOliver

+0

Không phải là câu trả lời mà là nhận xét về mã của bạn. Không có lý do nào để định nghĩa một hàm tạo bản sao như vậy, vì các hàm mặc định sẽ làm chính xác như vậy. Cũng thường có lý do để khai báo một hàm tạo bản sao rõ ràng, vì mục đích của nó là ngăn chặn các chuyển đổi kiểu ngầm định. – MikeMB

Trả lời

5

Bạn định nghĩa một constructor sao chép rõ ràng, nhưng các chức năng

Vector Vector::operator+(const Vector& v) const 

Vector Vector::operator-(const Vector& v) const 

phải trả lại theo giá trị, và có thể không nữa, do explicit (nói cách khác, họ không thể sao chép tmp vào đối tượng trả về).

Tôi cũng đã kiểm tra công cụ mới từ C++ 11 và xảy ra mà tôi có thể tuyên bố constructor của tôi giống như một chuyển động-constructor explicit Vector(const Vector&& v); và mã biên dịch tốt. Nếu tôi làm điều đó, tôi có phải có cả hai bản sao và di chuyển các nhà thầu không?

Không chắc chắn tôi hiểu ý của bạn ở đây. Bạn sẽ có cùng một vấn đề nếu bạn chỉ khai báo một hàm khởi tạo rõ ràng (điều này sẽ ngăn trình biên dịch tạo ra một hàm tạo bản sao mặc định). Tôi không thể sản xuất một mã "có thể tổng hợp" được.

+0

Tôi nghĩ rằng tôi đã làm rối tung mọi thứ. Giá trị trả về, nó là một giá trị hoặc một rvalue? Nếu nó là một ** rvalue **, tôi không thể, thay vì sao chép 'tmp', hãy sử dụng hàm khởi tạo di chuyển hoặc thao tác di chuyển mới trong C++ 11 ?. Nếu nó là một ** lvalue ** thì hàm sẽ luôn sao chép giá trị? là có bất kỳ tối ưu hóa từ trình biên dịch? – BRabbit27

+3

@ BRabbit27 lợi nhuận là một rvalue, và trình biên dịch thực hiện tối ưu hóa bất cứ khi nào có thể (nó được gọi là * tối ưu hóa giá trị trả về *, hoặc RVO). Tuy nhiên, nếu bạn khai báo các constructor di chuyển/copy 'clear', ngay cả khi tối ưu hóa về nguyên tắc có thể, trình biên dịch vẫn phàn nàn về việc' clear' business. Đó là chủ yếu bởi vì trình biên dịch đầu tiên thực hiện phân tích chính xác của chương trình của bạn, sau đó áp dụng tối ưu hóa. Mã phải là C++ hợp lệ trước giai đoạn tối ưu hóa. – vsoftco

+1

@ BRabbit27 và trong C++ 11, trình biên dịch đầu tiên cố gắng di chuyển đối tượng được trả về (nếu có thể), nếu không, sẽ tìm một trình tạo bản sao để sao chép nó và nếu nó vẫn không tìm thấy nó phát ra lỗi . Đó là trường hợp ở đây, bạn không có bất kỳ nhà xây dựng sao chép/di chuyển tiềm ẩn nào. – vsoftco

0

Trả về một đối tượng theo giá trị yêu cầu có thể thực hiện xây dựng bản sao ẩn. Làm cho hàm tạo bản sao rõ ràng ngăn cản điều đó.

Điều này đúng dù trình biên dịch có chọn không gọi trình tạo bản sao (ví dụ: tối ưu hóa giá trị trả về) hay không.

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