Il primo caso non esegue una doppia assegnazione, esegue due allocazioni, uno per l'oggetto gestito e uno per il blocco controllo del shared_ptr
.
Per il secondo caso, cppreference ha una buona spiegazione del perché std::make_sharedsolito esegui solo un'allocazione di memoria si dice (sottolineatura mia andando avanti):
Questa funzione alloca tipicamente memoria per il T oggetto e per il blocco di controllo shared_ptr con una singola allocazione di memoria (è un requisito non vincolante nello standard nello standard). Al contrario, la dichiarazione std :: shared_ptr p (new T (Args ...)) esegue almeno due allocazioni di memoria , che potrebbero comportare inutili spese generali.
e da std::shared_ptr sezione che dice: si crea
Quando shared_ptr viene creato chiamando std :: make_shared o std :: allocate_shared, la memoria sia per il blocco di controllo e l' oggetto gestito con una singola allocazione. L'oggetto gestito viene creato sul posto in un membro dati del blocco di controllo. Quando shared_ptr viene creato tramite uno dei costruttori shared_ptr, l'oggetto gestito e il blocco di controllo deve essere assegnato separatamente. Nel caso , il blocco di controllo memorizza un puntatore all'oggetto gestito.
Questa descrizione make_shared
è coerente con la C++11 draft standard che dice nella sezione 20.7.2.2.6
creazione shared_ptr
template<class T, class... Args> shared_ptr<T> make_shared(Args&&... args);
template<class T, class A, class... Args>
shared_ptr<T> allocate_shared(const A& a, Args&&... args);
[...]
Osservazione: Implementazioni dovrebbe eseguire non più di un memoria allocazione. [Nota: questo fornisce l'efficienza equivalente a un puntatore intelligente intrusivo . -end note]
[Nota: in genere queste funzioni allocano più memoria di sizeof (T) per consentire le strutture di contabilità interna come i conteggi di riferimento .-end nota]
Herb Sutter ha una spiegazione più dettagliata dei vantaggi di utilizzare make_shared
in GotW #89 Solution: Smart Pointers ed evidenzia alcuni vantaggi:
- Si riduce assegnazione sovraccarico
- Migliora frazione.
- Evita un nuovo esplicito.
- Evita un problema di sicurezza delle eccezioni.
Tenere presente che quando si utilizza std::weak_ptrusing make_shared has some disadvantages.
Per essere chiari, non è una doppia allocazione di 'int'. Sono solo due allocazioni separate: una per l'oggetto 'int' e un'altra per il blocco di controllo' shared_ptr'. La seconda riga è solo una singola allocazione sia del 'int' che del blocco di controllo in un colpo solo. –
vedere il punto 2 qui: http://herbsutter.com/2013/05/29/gotw-89-solution-smart-pointers/ – perreal
Nel secondo caso 'make_shared' alloca sia il' int' che il blocco di controllo ed è quindi libero di allocare entrambi in una volta. Nel primo caso allocate 'int' e il costruttore di' shared_ptr' alloca il blocco di controllo e non c'è modo di unire le allocazioni. – nwp