Saya ingin meneruskan penunjuk bersama ke suatu fungsi. Bisakah Anda membantu saya dengan itu?
Tentu, saya bisa bantu soal itu. Saya berasumsi Anda memiliki pemahaman tentang semantik kepemilikan di C ++. Benarkah itu?
Ya, saya cukup nyaman dengan subjek ini.
Baik.
Oke, saya hanya bisa memikirkan dua alasan untuk shared_ptr
berargumen:
- Fungsi ingin berbagi kepemilikan objek;
- Fungsi ini melakukan beberapa operasi yang bekerja secara spesifik pada
shared_ptr
s.
Yang mana yang Anda minati?
Saya mencari jawaban umum, jadi saya sebenarnya tertarik pada keduanya. Saya ingin tahu tentang apa yang Anda maksud dalam kasus # 2.
Contoh dari fungsi tersebut termasuk std::static_pointer_cast
, pembanding kustom, atau predikat. Misalnya, jika Anda perlu menemukan semua shared_ptr unik dari vektor, Anda memerlukan predikat seperti itu.
Ah, ketika fungsinya benar-benar perlu memanipulasi smart pointer itu sendiri.
Persis.
Dalam hal ini, saya pikir kita harus melewati referensi.
Iya. Dan jika itu tidak mengubah penunjuk, Anda ingin melewati referensi const. Tidak perlu menyalin karena Anda tidak perlu berbagi kepemilikan. Itu skenario lainnya.
OK mengerti. Mari kita bicara tentang skenario lainnya.
Di mana Anda berbagi kepemilikan? Baik. Bagaimana Anda berbagi kepemilikan dengan shared_ptr
?
Dengan menyalinnya.
Maka fungsi tersebut perlu membuat salinan dari a shared_ptr
, benar?
Jelas sekali. Jadi saya meneruskannya dengan referensi ke const dan menyalin ke variabel lokal?
Tidak, itu pesimisasi. Jika diteruskan oleh referensi, fungsi tidak punya pilihan selain membuat salinan secara manual. Jika itu dilewatkan oleh nilai kompilator akan memilih pilihan terbaik antara salinan dan pemindahan dan melakukannya secara otomatis. Jadi, lewati nilai.
Poin yang bagus. Saya harus lebih sering mengingat artikel " Want Speed? Pass by Value ".
Tunggu, bagaimana jika fungsi tersebut menyimpan shared_ptr
dalam variabel anggota, misalnya? Bukankah itu akan membuat salinan yang berlebihan?
Fungsi tersebut dapat dengan mudah memindahkan shared_ptr
argumen ke penyimpanannya. Memindahkan shared_ptr
murah karena tidak mengubah jumlah referensi apa pun.
Ah, ide bagus.
Tetapi saya memikirkan skenario ketiga: bagaimana jika Anda tidak ingin memanipulasi shared_ptr
, atau berbagi kepemilikan?
Dalam hal ini, shared_ptr
sama sekali tidak relevan dengan fungsinya. Jika Anda ingin memanipulasi orang yang ditunjuk, ambil orang yang ditunjuk, dan biarkan penelepon memilih semantik kepemilikan yang mereka inginkan.
Dan haruskah saya mengambil poin tersebut dengan referensi atau nilai?
Aturan biasa berlaku. Petunjuk cerdas tidak mengubah apa pun.
Lewati nilai jika saya akan menyalin, meneruskan referensi jika saya ingin menghindari salinan.
Baik.
Hmm. Saya pikir Anda lupa skenario lain. Bagaimana jika saya ingin berbagi kepemilikan, tetapi hanya bergantung pada kondisi tertentu?
Ah, kasus tepi yang menarik. Saya tidak berharap itu sering terjadi. Tetapi ketika itu terjadi, Anda dapat meneruskan nilai dan mengabaikan salinannya jika Anda tidak membutuhkannya, atau meneruskan referensi dan membuat salinannya jika Anda membutuhkannya.
Saya mengambil risiko satu salinan yang berlebihan di opsi pertama, dan kehilangan potensi perpindahan di opsi kedua. Tidak bisakah saya makan kue dan memakannya juga?
Jika Anda berada dalam situasi di mana itu benar-benar penting, Anda dapat memberikan dua kelebihan, satu mengambil referensi nilai konstanta, dan yang lainnya mengambil referensi nilai r. Satu salinan, yang lainnya bergerak. Templat fungsi penerusan sempurna adalah opsi lain.
Saya pikir itu mencakup semua kemungkinan skenario. Terima kasih banyak.
const std::shared_ptr<myClass>& arg1