Trong C++, nếu bạn có một vòng lặp for rằng "bản sao" đối tượng của một người dùng loại được xác định sử dụng một constructor chuyển [...]
Trước hết, một constructor di chuyển được sử dụng cho di chuyển-xây dựng, thường có nghĩa là bạn không "sao chép": bạn có thể nhận ra di chuyển là sao chép - trên thực tế, một lớp có khả năng sao chép cũng có thể chuyển động - nhưng sau đó tại sao xác định hàm tạo di chuyển một cách rõ ràng?
[...] có tạo sự khác biệt nào nếu bạn sử dụng ++ i hoặc i ++ làm bộ đếm vòng lặp không?
Phụ thuộc vào số i
là. Nếu nó là một đối tượng vô hướng, như là int
, thì không có sự khác biệt nào cả.
Nếu i
là một đẳng cấp loại iterator, mặt khác, ++i
nên hiệu quả hơn (trên mặt đất thuần túy lý thuyết), bởi vì việc thực hiện operator ++
sẽ không cần phải tạo một bản sao của iterator để được trả lại trước khi bản thân trình vòng lặp được tăng lên.
Ở đây, ví dụ, là cách stdlibC++ định nghĩa các nhà khai thác tăng cho các loại iterator của một std::list
:
_Self&
operator++()
{
_M_node = _M_node->_M_next;
return *this;
}
_Self
operator++(int)
{
_Self __tmp = *this;
_M_node = _M_node->_M_next;
return __tmp;
}
Như bạn có thể thấy, phiên bản postfix (một sự chấp nhận một giả int
) có làm việc nhiều hơn cần làm: nó cần tạo một bản sao của trình lặp ban đầu để được phục hồi, sau đó thay đổi con trỏ bên trong của trình lặp, sau đó trả về bản sao.
Mặt khác, phiên bản tiền tố chỉ cần thay đổi con trỏ bên trong và trả về (tham chiếu đến) chính nó.
Tuy nhiên, xin lưu ý rằng khi hiệu suất là có liên quan, tất cả các giả định phải được sao lưu bằng cách đo lường. Trong trường hợp này, tôi không mong đợi bất kỳ sự khác biệt hợp lý giữa hai chức năng này.
Xem thêm [Giải pháp GotW # 2 của Herb Sutter]: http://herbsutter.com/2013/05/13/gotw-2-solution-temporary-objects/). – jww