Ich stimme dem Konsens zu, dass es im Allgemeinen am besten ist, C ++ - Datenelemente in einer Elementinitialisierungsliste und nicht als Hauptteil eines Konstruktors zu initialisieren, aber ich bin skeptisch gegenüber c++ constructor performance assignment-operator member-initialization
Verwenden der Member-Initialisierungsliste,
%Vor% Clang 3.9.1 und gcc 6.3 generieren Folgendes mit -O3 -fno-exceptions
( Compiler-Explorer ):
Wenn wir stattdessen eine Aufgabe im Körper ausführen:
%Vor%erzeugt viel mehr Code, z.B. Clang 3.9.1 gibt folgendes aus:
%Vor%So scheint es, dass Mitglieder-Init-Listen tatsächlich effizienter sind, zumindest in einigen Fällen sogar mit modernen Compilern.
In den Worten von Alexandrescu & amp; Sutter (Punkt 9) Nicht zu früh pessimisieren
Eine vorzeitige Optimierung zu vermeiden, bedeutet nicht, dass Sie unnötige Schmerzen haben Effizienz. Mit voreiliger Pessimisierung meinen wir, so unentgeltlich zu schreiben potenzielle Ineffizienzen wie:
• Definition von Pass-by-Value-Parametern bei Pass-by-Reference angemessen. (Siehe Punkt 25.)
• Verwenden Sie postfix + +, wenn die Präfixversion genauso gut ist. (Sehen Punkt 28.)
• Verwenden der Zuweisung in Konstruktoren anstelle des Initialisierers Liste. (Siehe Punkt 48.)
Immer wenn Sie Aufgaben in Konstruktoren schreiben, werden Ihre Code-Reviewer in Alarmbereitschaft sein: Ist etwas Besonderes im Gange? Wollte er wirklich eine spezielle zweistufige Initialisierung (weil es eine implizite Standardkonstruktion des Mitglieds gibt, das sowieso erzeugt wird!). Überraschen Sie die Leser Ihres Codes nicht unnötig.
Beachten Sie, dass Alexandrescu & amp; Sutter geht in Punkt 48 weiter, um die potentielle Ineffizienz zu diskutieren, aber behaupten nirgendwo, dass es eine tatsächliche Ineffizienz in echtem optimierten Code gibt. Das ist auch nebensächlich, es geht darum, Absicht auszudrücken und das Risiko der Ineffizienz zu vermeiden.
Sind Mitgliederinitialisierungslisten tatsächlich effizienter? Wenn ja, ist es aus diesem Grund?
Allgemein ja. Bei der Elementinitialisierung übergeben Sie den Wert direkt an einen Konstruktor, andernfalls würde ein standardmäßig erstelltes Objekt erstellt und dann der Zuweisungsoperator aufgerufen. Beachten Sie, dass es sich nicht um "temporär" handelt, das in dem von Ihnen angegebenen Zitat erwähnt wird, sondern um das Feld selbst.
Sie können es live hier sehen
%Vor%Ausgabe:
%Vor%Tags und Links c++ constructor performance assignment-operator member-initialization