Heim > Backend-Entwicklung > C++ > „make_shared' vs. vom Konstruktor initialisiertes „shared_ptr': Was ist der Unterschied in Leistung und Ausnahmesicherheit?

„make_shared' vs. vom Konstruktor initialisiertes „shared_ptr': Was ist der Unterschied in Leistung und Ausnahmesicherheit?

Barbara Streisand
Freigeben: 2024-12-11 00:40:16
Original
403 Leute haben es durchsucht

`make_shared` vs. Constructor-Initialized `shared_ptr`: What's the Performance and Exception Safety Difference?

Unterschied zwischen make_shared und Constructor-Initialized shared_ptr

Szenario

Berücksichtigen Sie die folgenden Codeausschnitte:

std::shared_ptr<Object> p1 = std::make_shared<Object>("foo");
std::shared_ptr<Object> p2(new Object("foo"));
Nach dem Login kopieren

Verstehen, warum make_shared ist effizienter als die direkte Verwendung des shared_ptr-Konstruktors eine schrittweise Analyse der beteiligten Vorgänge.

Operationsvergleich

make_shared

  • Führt eine einzelne Heap-Zuweisung durch, um einen zusammenhängenden Speicherblock für beide zu erstellen Kontrollblock (Metadaten) und das verwaltete Objekt.

Konstruktor-initialisiert shared_ptr

  • Ruft new Obj("foo") auf, das eine Heap-Zuweisung für das verwaltete Objekt erstellt.
  • Dann wird der shared_ptr-Konstruktor aufgerufen, der eine weitere Heap-Zuweisung für das durchführt Steuerblock.

Speicherzuweisungen

make_shared reserviert Speicher nur einmal, während der vom Konstruktor initialisierte shared_ptr Speicher zweimal zuweist. Dies macht make_shared effizienter.

Ausnahmesicherheit

In C 17 wurde die Auswertungsreihenfolge von Funktionsargumenten überarbeitet, wodurch ein Ausnahmesicherheitsrisiko beim Konstruktor-initialisierten shared_ptr-Ansatz beseitigt wurde. Betrachten wir jedoch das Beispiel:

void F(const std::shared_ptr<Lhs> &lhs, const std::shared_ptr<Rhs> &rhs) { /* ... */ }

F(std::shared_ptr<Lhs>(new Lhs("foo")), std::shared_ptr<Rhs>(new Rhs("bar")));
Nach dem Login kopieren

Wenn während des Rhs-Konstruktors eine Ausnahme ausgelöst wird, geht der für Lhs zugewiesene Speicher verloren, da er nicht sofort an den shared_ptr-Konstruktor übergeben wurde. make_shared vermeidet dieses Problem, indem es diesen Zwischenschritt eliminiert.

Nachteil von make_shared

Make_shared hat jedoch einen Nachteil: Da es den Kontrollblock und das verwaltete Objekt in einem einzigen Heap-Block zuordnet, ist der Speicher für beide können nicht unabhängig voneinander freigegeben werden. Dies bedeutet, dass schwache Zeiger den Kontrollblock auf unbestimmte Zeit am Leben halten können, wodurch möglicherweise verhindert wird, dass sowohl der Kontrollblock als auch das verwaltete Objekt freigegeben werden.

Das obige ist der detaillierte Inhalt von„make_shared' vs. vom Konstruktor initialisiertes „shared_ptr': Was ist der Unterschied in Leistung und Ausnahmesicherheit?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Quelle:php.cn
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Neueste Artikel des Autors
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage