Ich habe oft gesehen, dass Leute Objekte in C ++ mit erstellen
Thing myThing("asdf");
An Stelle von:
Thing myThing = Thing("asdf");
Dies scheint zu funktionieren (mit gcc), zumindest solange keine Vorlagen beteiligt sind. Meine Frage ist jetzt, ist die erste Zeile richtig und wenn ja, sollte ich sie verwenden?
Antworten:
Beide Zeilen sind zwar korrekt, machen aber subtil unterschiedliche Dinge.
In der ersten Zeile wird ein neues Objekt auf dem Stapel erstellt, indem ein Konstruktor des Formats aufgerufen wird
Thing(const char*)
.Der zweite ist etwas komplexer. Es macht im Wesentlichen das Folgende
Thing
mit dem Konstruktor ein Objekt vom TypThing(const char*)
Thing
mit dem Konstruktor ein Objekt vom TypThing(const Thing&)
~Thing()
das in Schritt 1 erstellte Objekt aufquelle
Thing myThing = Thing(...)
verwendet den Zuweisungsoperator nicht, er ist wie gesagt immer nochThing myThing(Thing(...))
Thing
Ich nehme an, mit der zweiten Zeile meinen Sie tatsächlich:
Dies wäre die Standardmethode zum Erstellen neuer dynamischer Objekte (die für die dynamische Bindung und den Polymorphismus erforderlich sind) und zum Speichern ihrer Adresse in einem Zeiger. Ihr Code macht das, was JaredPar beschrieben hat, nämlich zwei Objekte zu erstellen (eines hat a übergeben
const char*
, das andere hat a übergebenconst Thing&
) und dann den Destruktor (~Thing()
) für das erste Objekt (dasconst char*
eine) aufzurufen .Im Gegensatz dazu:
Erstellt ein statisches Objekt, das beim Verlassen des aktuellen Bereichs automatisch zerstört wird.
quelle
Der Compiler kann das zweite Formular zwar in das erste Formular optimieren, muss es aber nicht.
Ausgabe von gcc 4.4:
quelle
Ganz einfach, beide Zeilen erstellen das Objekt auf dem Stapel und nicht wie 'neu' auf dem Heap. Die zweite Zeile beinhaltet tatsächlich einen zweiten Aufruf eines Kopierkonstruktors, daher sollte dies vermieden werden (sie muss auch wie in den Kommentaren angegeben korrigiert werden). Sie sollten den Stapel so oft wie möglich für kleine Objekte verwenden, da er schneller ist. Wenn Ihre Objekte jedoch länger als der Stapelrahmen überleben, ist dies eindeutig die falsche Wahl.
quelle
Im Idealfall würde ein Compiler die zweite optimieren, dies ist jedoch nicht erforderlich. Der erste ist der beste Weg. Es ist jedoch ziemlich wichtig, die Unterscheidung zwischen Stack und Heap in C ++ zu verstehen, da Sie Ihren eigenen Heap-Speicher verwalten müssen.
quelle
Ich habe ein bisschen damit gespielt und die Syntax scheint ziemlich seltsam zu werden, wenn ein Konstruktor keine Argumente akzeptiert. Lassen Sie mich ein Beispiel geben:
Wenn Sie also nur Thing myThing ohne Klammern schreiben, wird der Konstruktor aufgerufen, während Thing myThing () den Compiler dazu bringt, einen Funktionszeiger oder etwas anderes zu erstellen? !!
quelle
Im Anhang zur JaredPar- Antwort
1-üblicher ctor, 2.-funktion-ähnlicher-ctor mit temporärem Objekt.
Kompilieren Sie diese Quelle irgendwo hier http://melpon.org/wandbox/ mit verschiedenen Compilern
Und Sie werden das Ergebnis sehen.
Aus ISO / IEC 14882 2003-10-15
Ihre 1. und 2. Konstruktion werden als Direktinitialisierung bezeichnet
Wo kann man über RVO lesen:
Schalten Sie es mit dem Compiler-Flag aus dem Kommentar aus, um ein solches Kopierverhalten anzuzeigen.
quelle