Voglio passare un puntatore condiviso a una funzione. Puoi aiutarmi con quello?
Certo, posso aiutarti con te. Presumo che tu abbia una certa comprensione della semantica della proprietà in C ++. È vero?
Sì, sono abbastanza a mio agio con l'argomento.
Buona.
Ok, posso solo pensare a due motivi per sostenere un shared_ptr
argomento:
- La funzione vuole condividere la proprietà dell'oggetto;
- La funzione esegue alcune operazioni che funzionano specificamente su
shared_ptr
s.
Quale ti interessa?
Sto cercando una risposta generale, quindi in realtà sono interessato a entrambi. Sono curioso di sapere cosa intendi nel caso n. 2, però.
Esempi di tali funzioni includono std::static_pointer_cast
comparatori personalizzati o predicati. Ad esempio, se è necessario trovare tutti i shared_ptr univoci da un vettore, è necessario un tale predicato.
Ah, quando la funzione ha effettivamente bisogno di manipolare il puntatore intelligente stesso.
Esattamente.
In tal caso, penso che dovremmo passare per riferimento.
Sì. E se non cambia il puntatore, vuoi passare per riferimento const. Non è necessario copiare poiché non è necessario condividere la proprietà. Questo è l'altro scenario.
Ok capito. Parliamo dell'altro scenario.
Quello di cui condividi la proprietà? Ok. Come condividi la proprietà con shared_ptr
?
Copiandolo.
Quindi la funzione dovrà fare una copia di un shared_ptr
, corretto?
Ovviamente. Quindi lo passo con un riferimento a const e copio in una variabile locale?
No, è una pessimazione. Se viene passato per riferimento, la funzione non avrà altra scelta che eseguire la copia manualmente. Se viene passato per valore, il compilatore sceglierà la scelta migliore tra una copia e una mossa e la eseguirà automaticamente. Quindi, passa per valore.
Buon punto. Devo ricordare più spesso l'articolo " Vuoi velocità? Passa per valore ".
Aspetta, cosa succede se la funzione memorizza il shared_ptr
in una variabile membro, per esempio? Non sarà una copia ridondante?
La funzione può semplicemente spostare l' shared_ptr
argomento nella sua memoria. Spostare un shared_ptr
è economico perché non modifica alcun conteggio dei riferimenti.
Ah, buona idea.
Ma sto pensando a un terzo scenario: cosa succede se non si desidera manipolare shared_ptr
né condividere la proprietà?
In tal caso, shared_ptr
è completamente irrilevante per la funzione. Se vuoi manipolare le punte, prendi una punta e lascia che i chiamanti scelgano quale semantica di proprietà desiderano.
E dovrei prendere le punte per riferimento o per valore?
Si applicano le solite regole. I puntatori intelligenti non cambiano nulla.
Passa per valore se intendo copiare, passa per riferimento se voglio evitare una copia.
Destra.
Hmm. Penso che tu abbia dimenticato l'ennesimo scenario. E se volessi condividere la proprietà, ma solo in base a una determinata condizione?
Ah, un interessante caso limite. Non mi aspetto che succeda spesso. Ma quando succede puoi passare per valore e ignorare la copia se non ne hai bisogno, oppure passare per riferimento e fare la copia se ne hai bisogno.
Rischio una copia ridondante nella prima opzione e perdo una potenziale mossa nella seconda. Non posso mangiare la torta e averla anche io?
Se ti trovi in una situazione in cui questo è davvero importante, puoi fornire due overload, uno che prende un riferimento const lvalue e un altro che prende un riferimento rvalue. Uno copia, l'altro si muove. Un modello di funzione di inoltro perfetto è un'altra opzione.
Penso che copra tutti i possibili scenari. Grazie mille.
const std::shared_ptr<myClass>& arg1