Ho appena letto il libro classico "Effective C++, 3rd Edition", e nell'articolo 20 l'autore conclude che i tipi incorporati , gli iteratori STL e gli oggetti funzione sono più appropriato per pass-by-value. Potrei ben capire il motivo per i tipi built-in e iterator, ma perché l'oggetto funzione dovrebbe essere pass-by-value, poiché sappiamo che è comunque di classe?perché gli oggetti funzione devono essere pass-by-value
risposta
In un caso tipico, un oggetto funzione avrà poco o (più spesso) nessuno stato persistente. In tal caso, passare per valore potrebbe non richiedere in realtà alcun passaggio - il "valore" che viene passato è praticamente poco o nulla più di un segnaposto per "questo è l'oggetto".
Data la piccola quantità di codice in molti oggetti funzione, ciò porta ad un'ulteriore ottimizzazione: è spesso abbastanza facile per il compilatore espandere il codice per l'oggetto funzione in linea, quindi nessun parametro viene passato e nessuna chiamata di funzione è coinvolto a tutti.
Un compilatore può essere in grado di fare lo stesso quando si passa un puntatore o riferimento, invece, ma non è così facile - molto più comune che si ritroverà con un oggetto che viene creato, il suo indirizzo passato, e quindi la funzione chiama operatore per quell'oggetto che viene invocato tramite quel puntatore.
Modifica: Probabilmente vale anche la pena menzionare che lo stesso vale per i lambda, dal momento che sono in realtà solo oggetti funzione mascherati. Non si conosce il nome della classe, ma creano una classe nell'ambito immediatamente circostante che sovraccarica l'operatore della chiamata di funzione, che è ciò che viene invocato quando si "chiama" il lambda. [Grazie a @Mark Garcia.]
Grazie per la spiegazione, e la parte "ottimizzazione in linea" mi impressiona molto. – JavaBeta
La mia esperienza lavorativa mostra che l'ampio uso di 'boost :: bind' porta a oggetti funzione che sono costosi da copiare. Sembra aumentare in modo esponenziale la profondità del binding (vincolando un callback che ha richiamato la callback all'interno ecc.) –
Da efficace STL (poiché sembra che gli piaccia Scott Meyers) articolo 38 Design classi di funzionamento per pass-per-valore.
"In C e C++, i puntatori di funzione vengono passati per il valore STL Gli oggetti funzione vengono modellati dopo i puntatori di funzione, quindi la convenzione nell'STL è che anche gli oggetti funzione vengono passati per valore quando passano ae da funzioni. "
Questo ha alcuni vantaggi e alcune implicazioni, come ha detto @Jerry Coffin, il compilatore può fare alcune ottimizzazioni come inlining del codice per evitare chiamate di funzione Un buon esempio di questo caso è il confronto delle prestazioni qsort vs std :: sort, dove std :: sort usando i functors inline superano qsort di molto, potete trovare maggiori informazioni su questo su AWL efficace dove è discusso ampiamente e menzionato in diversi capitoli.
Anche questo ha diverse implicazioni, poiché gli oggetti funzione vengono passati e restituiti in base al valore, è necessario assicurarsi che l'oggetto disponga di meccanismi di copia ben definiti, di dimensioni ridotte (altrimenti potrebbe essere costoso) e monomorfico (dal momento che il passaggio di oggetti polimorfici in base al valore può causare l'affettamento di oggetti).
Le serie efficaci di Meyers sono molto popolari in Cina :-). Inoltre, grazie per la spiegazione della differenza tra std :: sort e std :: qsort. – JavaBeta
Il motivo n. 1 per passare gli oggetti funzione in base al valore è perché la libreria standard richiede che gli oggetti funzione che si passano ai suoi algoritmi siano copiabili. C++ 11 §25.1/10:
[Nota: Se non diversamente specificato, gli algoritmi che prendono oggetti funzione come argomenti sono autorizzati a copiare quelle funzione oggetti liberamente. I programmatori per i quali l'identità dell'oggetto è importante dovrebbero prendere in considerazione l'utilizzo di una classe wrapper che punta a un oggetto di implementazione non protetto come
reference_wrapper<T>
(20.8.3), o una soluzione equivalente.-end note]
Le altre risposte fanno un ottimo lavoro di spiegazione della logica.
- 1. Solo gli oggetti devono essere cancellati
- 2. Perché gli oggetti lanciati devono essere inizializzati in copia?
- 3. Perché gli oggetti Java devono essere multipli di 8?
- 4. Gli oggetti NSString devono essere alloc e init?
- 5. Gli oggetti aziendali o le entità devono essere autovalegnati?
- 6. Gli oggetti entità devono essere esposti dal repository?
- 7. Gli oggetti di posta elettronica devono essere salvati in html?
- 8. Perché gli array statici non devono essere liberati?
- 9. Perché gli oggetti di trasferimento devono implementare Serializable?
- 10. ui-router Perché gli stati parentali devono essere astratti
- 11. Perché non tutti gli argomenti della funzione devono essere dichiarati definitivi?
- 12. Gli elementi vettoriali devono essere mobili?
- 13. Gli ETAG HTTP devono essere case sensitive?
- 14. Perché i bean Java devono essere serializzabili?
- 15. Perché i metodi parziali devono essere annullati?
- 16. Perché i tipi WinRT devono essere sigillati?
- 17. Perché gli oggetti in Redux dovrebbero essere immutabili?
- 18. Gli oggetti del dominio e i JavaBeans semplici devono essere testati unitamente?
- 19. Come specificare che gli oggetti DateTime recuperati da EntityFramework devono essere DateTimeKind.UTC
- 20. Quando devono essere specificati in modo esplicito gli interi?
- 21. Perché i parametri di restituzione devono essere denominati?
- 22. Perché i sindacati anonimi globali devono essere dichiarati come statici?
- 23. Quando devono essere scritti gli scenari di test BDD?
- 24. TypeError: gli indici tuple devono essere numeri interi, non str
- 25. Gli oggetti enum dovrebbero essere apolidi?
- 26. Come possono essere usati gli oggetti spostati?
- 27. Perché gli oggetti restituiti da bind ignorano gli argomenti extra?
- 28. Perché gli interpreti di lingua devono essere scritti nella lingua di destinazione?
- 29. Gli array non devono essere inizializzati staticamente da un inizializzatore di array. Perché?
- 30. Perché un messaggio SOAP devono essere inviati tramite HTTP?
+1 per aver letto Effetto C++ – Borgleader
Gli oggetti funzione raramente devono avere un sovraccarico. – chris
Almeno, è più logico (tutti gli oggetti, in generale) ora che c'è la semantica del movimento. –