Các hoạt động di chuyển (như công cụ di chuyển) std::shared_ptr
rất rẻ , vì về cơ bản chúng là "đánh cắp con trỏ" (từ nguồn đến đích; chính xác hơn, toàn bộ khối điều khiển trạng thái bị "đánh cắp" từ nguồn đến đích, bao gồm cả thông tin đếm tham chiếu) .
Thay vào đó, sao chép các hoạt động khi std::shared_ptr
gọi tăng số tham chiếu nguyên tử (nghĩa là không chỉ ++RefCount
trên một RefCount
thành viên dữ liệu số nguyên , mà ví dụ như gọi InterlockedIncrement
trên Windows), tốn kém hơn so với chỉ ăn cắp con trỏ / trạng thái.
Vì vậy, phân tích động lực đếm ref của trường hợp này một cách chi tiết:
// shared_ptr<CompilerInvocation> sp;
compilerInstance.setInvocation(sp);
Nếu bạn chuyển sp
theo giá trị và sau đó lấy một bản sao bên trong CompilerInstance::setInvocation
phương thức, bạn có:
- Khi nhập phương thức,
shared_ptr
tham số được sao chép được xây dựng: số lần tăng nguyên tử ref .
- Bên trong cơ thể của phương pháp, bạn sao chép các
shared_ptr
tham số vào các thành viên dữ liệu: Ref đếm nguyên tử tăng .
- Khi thoát khỏi phương thức,
shared_ptr
tham số bị hủy: ref đếm giảm nguyên tử .
Bạn có hai mức tăng nguyên tử và một lần giảm nguyên tử, với tổng số ba hoạt động nguyên tử .
Thay vào đó, nếu bạn truyền shared_ptr
tham số theo giá trị và sau đó std::move
bên trong phương thức (như được thực hiện đúng trong mã của Clang), bạn có:
- Khi nhập phương thức,
shared_ptr
tham số được sao chép được xây dựng: số lần tăng nguyên tử ref .
- Bên trong cơ thể của phương pháp, bạn
std::move
các shared_ptr
tham số vào các thành viên dữ liệu: số lượng ref không không thay đổi! Bạn chỉ đang ăn cắp con trỏ / trạng thái: không có hoạt động đếm số nguyên tử đắt tiền nào được tham gia.
- Khi thoát khỏi phương thức,
shared_ptr
tham số bị hủy; nhưng vì bạn đã chuyển sang bước 2, nên không có gì để hủy, vì shared_ptr
tham số không còn trỏ đến bất cứ điều gì nữa. Một lần nữa, không có sự suy giảm nguyên tử xảy ra trong trường hợp này.
Điểm mấu chốt: trong trường hợp này bạn chỉ nhận được một lần tăng số nguyên tử, tức là chỉ một thao tác nguyên tử .
Như bạn có thể thấy, điều này tốt hơn nhiều so với hai mức tăng nguyên tử cộng với một lần giảm nguyên tử (cho tổng số ba thao tác nguyên tử) cho trường hợp sao chép.