Tôi sẽ không lo lắng về nó. Nếu bạn làm điều đó trong một vòng lặp, các chuỗi sẽ luôn phân bổ trước bộ nhớ để giảm thiểu việc phân bổ lại - chỉ sử dụng operator+=
trong trường hợp đó. Và nếu bạn làm điều đó theo cách thủ công, tương tự như thế này hoặc lâu hơn
a + " : " + c
Sau đó, nó tạo ra thời gian tạm thời - ngay cả khi trình biên dịch có thể loại bỏ một số bản sao giá trị trả về. Đó là bởi vì trong một lần gọi liên tiếp, operator+
nó không biết liệu tham số tham chiếu có tham chiếu đến một đối tượng được đặt tên hay tạm thời được trả về từ một lệnh operator+
gọi con hay không . Tôi không muốn lo lắng về nó trước khi không có hồ sơ đầu tiên. Nhưng hãy lấy một ví dụ cho thấy điều đó. Đầu tiên chúng tôi giới thiệu dấu ngoặc đơn để làm rõ ràng ràng buộc. Tôi đặt các đối số ngay sau khai báo hàm được sử dụng để làm rõ ràng. Dưới đó, tôi hiển thị biểu thức kết quả sau đó là:
((a + " : ") + c)
calls string operator+(string const&, char const*)(a, " : ")
=> (tmp1 + c)
Bây giờ, thêm vào đó, tmp1
là những gì được trả về bởi cuộc gọi đầu tiên tới toán tử + với các đối số được hiển thị. Chúng tôi cho rằng trình biên dịch thực sự thông minh và tối ưu hóa bản sao giá trị trả về. Vì vậy, chúng tôi kết thúc với một chuỗi mới chứa nối của a
và " : "
. Bây giờ, điều này xảy ra:
(tmp1 + c)
calls string operator+(string const&, string const&)(tmp1, c)
=> tmp2 == <end result>
So sánh điều đó với những điều sau:
std::string f = "hello";
(f + c)
calls string operator+(string const&, string const&)(f, c)
=> tmp1 == <end result>
Nó sử dụng cùng một hàm cho một chuỗi tạm thời và cho một chuỗi được đặt tên! Vì vậy, các trình biên dịch có để sao chép các đối số vào một chuỗi mới và append vào đó và gửi lại cho ra khỏi cơ thể của operator+
. Nó không thể lấy bộ nhớ của một tạm thời và thêm vào đó. Biểu thức càng lớn thì càng phải thực hiện nhiều bản sao của chuỗi.
Tiếp theo Visual Studio và GCC sẽ hỗ trợ ngữ nghĩa di chuyển của c ++ 1x (bổ sung ngữ nghĩa sao chép ) và các tham chiếu rvalue như một bổ sung thử nghiệm. Điều đó cho phép tìm hiểu xem tham số có tham chiếu tạm thời hay không. Điều này sẽ làm cho những bổ sung như vậy nhanh chóng đáng kinh ngạc, vì tất cả những điều trên sẽ kết thúc trong một "đường ống bổ sung" mà không có bản sao.
Nếu nó trở thành một nút cổ chai, bạn vẫn có thể làm
std::string(a).append(" : ").append(c) ...
Các append
lệnh gọi nối đối số vào *this
và sau đó trả về một tham chiếu cho chính chúng. Vì vậy, không có việc sao chép thời gian tạm thời được thực hiện ở đó. Hoặc cách khác, operator+=
có thể được sử dụng, nhưng bạn sẽ cần dấu ngoặc đơn xấu xí để sửa mức độ ưu tiên.