make_shared (<memory>)
Crea e restituisce un oggetto shared_ptr che punta all'oggetto allocato costruito da zero o più argomenti usando l'allocatore predefinito. Alloca e costruisce un oggetto del tipo specifico e shared_ptr per gestire la proprietà condivisa dell'oggetto e restituisce shared_ptr.
template<class Type, class... Types> shared_ptr<Type> make_shared( Types&&... _Args );
Parametri
Parametro |
Descrizione |
---|---|
_Args |
Zero o più argomenti del costruttore. La funzione deduce di quale costruttore eseguire l'overload per richiamare il costruttore in base agli argomenti forniti. |
Valore proprietà/Valore restituito
Restituisce shared_ptr che punta all'oggetto allocato e costruito.
Note
Usare make_shared come metodo semplice ed efficace per creare un oggetto e shared_ptr per gestire contemporaneamente l'accesso condiviso all'oggetto. Semanticamente, queste due istruzioni sono equivalenti:
auto sp = std::shared_ptr<Example>(new Example(argument));
auto msp = std::make_shared<Example>(argument);
Tuttavia, la prima istruzione crea due allocazioni e, se l'allocazione di shared_ptr non riesce dopo la corretta allocazione dell'oggetto Example, l'oggetto senza nome Example viene perso. L'istruzione che usa make_shared è più semplice perché comprende una sola chiamata di funzione. È più efficiente perché la libreria può eseguire una singola allocazione per l'oggetto e il puntatore intelligente. Questa funzionalità è più rapida e comporta una minore frammentazione della memoria. Inoltre, non esiste alcuna possibilità che si verifichi un'eccezione in una sola allocazione. Le prestazioni sono migliorate grazie a un posizionamento più preciso del codice che fa riferimento all'oggetto e aggiorna i conteggi dei riferimenti nel puntatore intelligente.
Se non è necessario un accesso condiviso all'oggetto, si consiglia di usare make_unique. Usare allocate_shared per specificare un'allocazione personalizzata per l'oggetto. Non è possibile usare make_shared se l'oggetto richiede un Deleter personalizzato perché non può essere passato come argomento.
Nell'esempio seguente viene mostrato come creare puntatori condivisi a un tipo richiamando overload specifici del costruttore.
Esempio
// stl_make_shared.cpp
// Compile by using: cl /W4 /EHsc stl_make_shared.cpp
#include <iostream>
#include <string>
#include <memory>
#include <vector>
class Song {
public:
std::wstring title_;
std::wstring artist_;
Song(std::wstring title, std::wstring artist) : title_(title), artist_(artist) {}
Song(std::wstring title) : title_(title), artist_(L"Unknown") {}
};
void CreateSharedPointers() {
// Okay, but less efficient to have separate allocations for
// Song object and shared_ptr control block.
auto song = new Song(L"Ode to Joy", L"Beethoven");
std::shared_ptr<Song> sp0(song);
// Use make_shared function when possible. Memory for control block
// and Song object are allocated in the same call:
auto sp1 = std::make_shared<Song>(L"Yesterday", L"The Beatles");
auto sp2 = std::make_shared<Song>(L"Blackbird", L"The Beatles");
// make_shared infers which constructor to use based on the arguments.
auto sp3 = std::make_shared<Song>(L"Greensleeves");
// The playlist vector makes copies of the shared_ptr pointers.
std::vector<std::shared_ptr<Song>> playlist;
playlist.push_back(sp0);
playlist.push_back(sp1);
playlist.push_back(sp2);
playlist.push_back(sp3);
playlist.push_back(sp1);
playlist.push_back(sp2);
for (auto&& sp : playlist) {
std::wcout << L"Playing " << sp->title_ <<
L" by " << sp->artist_ << L", use count: " <<
sp.use_count() << std::endl;
}
}
int main() {
CreateSharedPointers();
}
L'esempio produce il seguente output:
Requisiti
Intestazione: <memory>
Spazio dei nomi: std