Tôi có lớp mẫu vectơ số sau (vectơ để tính toán số). Tôi đang cố gắng làm cho nó viết D=A+B+C
trở nên khả thi, trong đó tất cả các biến đều có Vectơ
sự vật. MỘT
,B
Và C
Nó không nên được sửa đổi. Ý tưởng của tôi là sử dụng Toán tử vectơ+(Vector&& B)
vì vậy (hy vọng) từ B+C
giá trị trả về Vectơ
Sau đó, tất cả các bổ sung tiếp theo sẽ được lưu trữ trong đối tượng này, tức là việc lưu trữ Rvalue bị đánh cắp cho tất cả các bổ sung tiếp theo. Điều này nhằm loại bỏ việc tạo ra các đối tượng mới và dung lượng lưu trữ cần thiết.
Vấn đề của tôi là tôi có thể thấy từ câu lệnh đầu ra cho mỗi hàm được gọi là nó không bao giờ được gọi Toán tử vectơ+(Vector&& B)
. Tôi không hiểu tại sao, vì nếu tôi có chức năng ảo bị quá tải foo(Vectơ&& B)
Và foo(Vectơ&& B)
và thử foo(A+B+C)
, thì hàm thứ hai sẽ được gọi như tôi mong đợi.
Xin lỗi vì câu hỏi dài, nhưng đây là câu hỏi đầu tiên của tôi ở đây và tôi muốn làm cho nó rõ ràng nhất có thể.
Bất kỳ đề xuất nào về những gì tôi rõ ràng đang làm sai hoặc tại sao tôi không nên thử điều này sẽ được đánh giá rất cao.
mẫu
vectơ lớp
{
int n;
T*v;
Vectơ();
~Vector();
Vector(const Vector& B);
Vector(Vector&& B);
toán tử Vector nội tuyến+(const Vector& B) const;
toán tử Vector nội tuyến+(Vector&& B) const;
};
mẫu
Vector::Vector(const Vector& B)
{
...
}
mẫu
Vector::Vector(Vector&& B)
{
...
}
mẫu
Vector Vector::operator+(const Vector& B) const
{
Vectơ C;
...
trả lại C;
}
mẫu
Vector Vector::operator+(Vector&& B) const
{
...làm điều gì đó với B
trả lại B;
}
Trong biểu thức:
D=A+B+C
MỘT
Và B
là một giá trị, vì vậy hãy gọi A+B
gọi Vector::toán tử(const Vector&)
Nó trả về một giá trị, hãy gọi nó tmp
, vậy biểu thức con tiếp theo là tmp+C
.
C
cũng là một giá trị, nên một lần nữa nó gọi Vector::toán tử(const Vector&)
. Trả về một giá trị khác, hãy gọi nó tmp2
Biểu thức con cuối cùng là D=tmp2
, nhưng loại của bạn không có toán tử gán di chuyển, do đó toán tử gán sao chép được xác định ngầm sẽ được sử dụng.
tức là bạn không bao giờ gọi với giá trị ở phía bên phải toán tử+
và các biểu thức duy nhất có đối số giá trị là các phép gán mà bạn chưa xác định cho giá trị.
Xác định quá tảikhông phải thành viêntoán tử sẽ tốt hơn:
Toán tử vectơ+(const Vector&, const Vector&);
Toán tử vectơ+(Vector&&, const Vector&);
Toán tử vectơ+(const Vector&, Vector&&);
Toán tử vectơ+(Vector&&, Vector&&);
Điều này áp dụng cho bất kỳ sự kết hợp nào giữa giá trị và giá trị. (Nói chung,toán tử+
Thông thường phải là một người không phải là thành viên. )
biên tập:Những gợi ý thay thế dưới đây không hiệu quả và có thể dẫn đến sự mơ hồ trong một số trường hợp.
Một tùy chọn khác, nếu trình biên dịch của bạn hỗ trợ nó (tôi nghĩ chỉ clang mới có) sẽ giữ nguyên hiện tại của bạn Vectơ::toán tử+(Vector&&)
nhưng thay thế của bạn Vector::operator+( const Vector&)
Có hai tình trạng quá tải được phân biệt bằng vòng loại tham chiếu:
Vector Vector::operator+(const Vector& v) const&
{
Vector tmp(*this);
tmp += v;
trả lại tmp;
}
Vector Vector::operator+(const Vector& v)&&
{
*cái này += v;
trả về std::move(*this);
}
Nó được sử dụng lại khi nó được biết đến là một giá trị *cái này
, tức là nó sử dụng ngữ nghĩa di chuyển khi phía bên trái của phép cộng là một giá trị, so với mã ban đầu chỉ có thể sử dụng ngữ nghĩa di chuyển khi phía bên phải là một giá trị. (Lưu ý rằng đoạn mã trên giả sử bạn đã xác định thành viên như được đề xuất trong câu trả lời của David Rodriguez toán tử+=
)
Tôi là một lập trình viên xuất sắc, rất giỏi!