Tôi muốn chuyển một con trỏ dùng chung cho một hàm. Bạn có thể giúp tôi với đó?
Chắc chắn, tôi có thể giúp bạn điều đó. Tôi giả sử bạn có một số hiểu biết về ngữ nghĩa quyền sở hữu trong C ++. Có đúng như vậy không?
Vâng, tôi hoàn toàn thoải mái với chủ đề này.
Tốt.
Được rồi, tôi chỉ có thể nghĩ ra hai lý do để shared_ptr
tranh luận:
- Hàm muốn chia sẻ quyền sở hữu đối tượng;
- Hàm thực hiện một số thao tác hoạt động cụ thể trên
shared_ptr
s.
Bạn quan tâm đến cái nào?
Tôi đang tìm kiếm một câu trả lời chung, vì vậy tôi thực sự quan tâm đến cả hai. Tuy nhiên, tôi tò mò về ý của bạn trong trường hợp số 2.
Ví dụ về các hàm như vậy bao gồm std::static_pointer_cast
, bộ so sánh tùy chỉnh hoặc vị từ. Ví dụ: nếu bạn cần tìm tất cả shared_ptr duy nhất từ một vectơ, bạn cần một vị từ như vậy.
À, khi hàm thực sự cần tự thao tác con trỏ thông minh.
Chính xác.
Trong trường hợp đó, tôi nghĩ chúng ta nên chuyển qua tham chiếu.
Đúng. Và nếu nó không thay đổi con trỏ, bạn muốn chuyển bằng tham chiếu const. Không cần sao chép vì bạn không cần chia sẻ quyền sở hữu. Đó là một kịch bản khác.
OK đã nhận nó. Hãy nói về kịch bản khác.
Người mà bạn chia sẻ quyền sở hữu? Đồng ý. Làm thế nào để bạn chia sẻ quyền sở hữu shared_ptr
?
Bằng cách sao chép nó.
Sau đó, hàm sẽ cần tạo một bản sao của a shared_ptr
, đúng không?
Chắc chắn. Vì vậy, tôi chuyển nó bằng một tham chiếu đến const và sao chép vào một biến cục bộ?
Không, đó là một sự bi quan. Nếu nó được truyền bằng tham chiếu, hàm sẽ không có lựa chọn nào khác ngoài việc tạo bản sao theo cách thủ công. Nếu nó được chuyển theo giá trị, trình biên dịch sẽ chọn lựa chọn tốt nhất giữa một bản sao và một lần di chuyển và thực hiện nó tự động. Vì vậy, hãy vượt qua giá trị.
Điểm tốt. Tôi phải nhớ rằng bài viết " Muốn Tốc độ? Vượt qua Giá trị. " Thường xuyên hơn.
Chờ đã, điều gì sẽ xảy ra nếu hàm lưu trữ shared_ptr
trong một biến thành viên, chẳng hạn? Điều đó sẽ không tạo ra một bản sao thừa phải không?
Hàm có thể chỉ cần di chuyển shared_ptr
đối số vào bộ nhớ của nó. Di chuyển a shared_ptr
là rẻ vì nó không thay đổi bất kỳ số lượng tham chiếu nào.
À, ý kiến hay.
Nhưng tôi đang nghĩ đến một kịch bản thứ ba: điều gì sẽ xảy ra nếu bạn không muốn thao túng shared_ptr
hoặc chia sẻ quyền sở hữu?
Trong trường hợp đó, shared_ptr
hoàn toàn không liên quan đến chức năng. Nếu bạn muốn thao túng con trỏ, hãy lấy con trỏ và để người gọi chọn ngữ nghĩa quyền sở hữu mà họ muốn.
Và tôi nên lấy pointee theo tham chiếu hay theo giá trị?
Các quy tắc thông thường được áp dụng. Con trỏ thông minh không thay đổi bất cứ điều gì.
Chuyển theo giá trị nếu tôi định sao chép, chuyển bằng tham chiếu nếu tôi muốn tránh sao chép.
Đúng.
Hừ! Tôi nghĩ bạn đã quên một kịch bản khác. Nếu tôi muốn chia sẻ quyền sở hữu, nhưng chỉ phụ thuộc vào một điều kiện nhất định thì sao?
Ah, một trường hợp cạnh thú vị. Tôi không mong điều đó xảy ra thường xuyên. Nhưng khi nó xảy ra, bạn có thể chuyển theo giá trị và bỏ qua bản sao nếu bạn không cần nó hoặc chuyển bằng tham chiếu và tạo bản sao nếu bạn cần.
Tôi mạo hiểm với một bản sao thừa trong tùy chọn đầu tiên và mất một nước đi tiềm năng trong tùy chọn thứ hai. Tôi không thể ăn bánh và có nó nữa?
Nếu bạn đang ở trong tình huống thực sự quan trọng, bạn có thể cung cấp hai quá tải, một lấy tham chiếu const lvalue và một lấy tham chiếu rvalue. Một bản sao, bản khác di chuyển. Một mẫu hàm chuyển tiếp hoàn hảo là một tùy chọn khác.
Tôi nghĩ rằng điều đó bao gồm tất cả các tình huống có thể xảy ra. Cảm ơn rât nhiều.
const std::shared_ptr<myClass>& arg1