Hat std::make_unique
irgendwelche Effizienzvorteile wie std::make_shared
?
Im Vergleich zum manuellen Konstruieren von std::unique_ptr
:
std::make_unique<int>(1); // vs
std::unique_ptr<int>(new int(1));
Die Motivation hinter make_unique
ist in erster Linie zweierlei:
make_unique
ist sicher zum Erstellen von temporären Dateien, wohingegen Sie bei expliziter Verwendung von new
die Regel beachten müssen, nicht unbenannte temporäre Dateien zu verwenden.
foo(make_unique<T>(), make_unique<U>()); // exception safe
foo(unique_ptr<T>(new T()), unique_ptr<U>(new U())); // unsafe*
Die Hinzufügung von make_unique
bedeutet schließlich, dass wir den Leuten sagen können, dass sie new
niemals verwenden sollen und nicht die vorherige Regel, dass sie new
niemals verwenden sollen, außer wenn Sie einen unique_ptr
erstellen.
Es gibt auch einen dritten Grund:
make_unique
erfordert keine redundante Typverwendung. unique_ptr<T>(new T())
-> make_unique<T>()
Keiner der Gründe besteht darin, die Laufzeiteffizienz zu verbessern, wie dies bei Verwendung von make_shared
der Fall ist (aufgrund der Vermeidung einer zweiten Zuweisung auf Kosten einer potenziell höheren Spitzenbelegung des Speichers).
* Es wird erwartet, dass C++ 17 eine Regeländerung enthält, die bedeutet, dass dies nicht länger unsicher ist. Siehe C++ Ausschusspapiere P0400R und P0145R .
std::make_unique
und std::make_shared
gibt es aus zwei Gründen:
std::unique_ptr
oder std::shared_ptr
Konstruktoren. (Siehe den Abschnitt Anmerkungen hier .)Es geht nicht wirklich um Laufzeiteffizienz. Es gibt das gewisse Etwas, dass der Steuerblock und das T
auf einmal zugewiesen werden, aber ich denke, das ist eher ein Bonus als eine Motivation für das Vorhandensein dieser Funktionen.
Ein Grund, warum Sie std::unique_ptr(new A())
oder std::shared_ptr(new A())
direkt anstelle von std::make_*()
verwenden müssten, besteht darin, dass Sie nicht auf den Konstruktor der Klasse A
außerhalb von zugreifen können aktueller Geltungsbereich.