C++11-member-Initialisierungsliste vs-in-class-Initialisierung?
Was ist der Unterschied zwischen diesen Arten der Initialisierung der Objekt-member-Variablen in C++11 ? Gibt es einen anderen Weg ? welcher Weg ist besser (Leistung) ?:
class any {
public:
obj s = obj("value");
any(){}
};
Oder
class any {
public:
obj s;
any(): s("value"){}
};
Dank.
- Sie sind die gleichen.
- Ich bin damit einverstanden, Sie sind die gleichen. Ich wollte nur hinzufügen, dass für weitere Referenz, die Sie Lesen können, "Die C++ Programmiersprache, 4. Auflage" Abschnitt 17.4.4.
- Sehr ähnlich zu die neue C++11-member-Initialisierung-Funktion zur Erklärung der Initialisierung Listen veraltet?
Du musst angemeldet sein, um einen Kommentar abzugeben.
Nein, diese sind nicht das gleiche.
Den Unterschied zwischen Ihnen ist die gleiche, gilt für direkt-Initialisierung vs. copy-Initialisierung, die subtilen, aber oft sehr verwirrend.
§12.6.2 [Klasse.base.init]:
§8.5 [dcl.init]:
Initialisierung einer nicht-statischen Daten-member auf eine Mitglied-Initialisierer-Liste folgt den Regeln der direkt-Initialisierung, die nicht erstellen intermediate Provisorien müssen verschoben/kopiert werden (wenn kompiliert ohne copy-elision), weder die Art der Daten, die das Mitglied muss kopierbar/verschiebbar (auch wenn die Kopie erstellte). Zusätzlich direkt-Initialisierung stellt einen expliziten Kontext, während ein copy-Initialisierung ist nicht-ausdrückliche (wenn ein Konstruktor ausgewählt, die für die Initialisierung ist
explicit
, das Programm wird nicht kompiliert).In anderen Worten, die
obj s = obj("value");
syntax nicht kompilieren, wennobj
ist deklariert als:oder:
Als greifbareres Beispiel, während die unten nicht kompilieren:
diese:
Mit einem copy-elision aktiviert, beide haben identische Leistung. Mit copy-elision deaktiviert ist, wird eine zusätzliche Kopie/move-Konstruktor-Aufruf nach jeder Instanziierung wenn die copy-Initialisierung - syntax verwendet wird (das
obj s = obj("value");
gehört).Den Klammer-oder-gleich-Initialisierer syntax erlaubt das ausführen einer direct-list-Initialisierung sowie:
Einige andere Unterschiede, die erwähnenswert sind:
obj s{"value"}
ist dem heap zugeordnet, danns
reserviert auf dem heap sowie. Ob Sie ordnen Daten, die Mitglieder auf stack/heap abhängig von design-Entscheidungen/weitere Verwendung dieser ObjekteBeiden Beispiele sind gleichwertig.
Allerdings nur, wenn der Typ ist kopierbar oder verschiebbar (überprüfen Sie es für sich selbst) und NRVO ist eigentlich fertig (jeder halbwegs gute compiler wird das nicht als Selbstverständlichkeit).
Obwohl, wenn Sie hatte viele Konstruktoren und Konstruktor-Verkettung geeignet waren, die erste Methode, die erlauben würde, Sie nicht zu wiederholen.
Können Sie auch die Methode zur Definition von Aggregaten mit Standardwerten aus verschiedenen Aggregat-Initialisierung für (einige) Mitglieder, denn C++14.
Sind Sie gleich.
Weder besser als die anderen in Bezug auf die Leistung, und es gibt keinen anderen Weg, initialisieren Sie Sie.
Den nutzen von in-class-Initialisierung (die erste in deinem Beispiel) ist, dass die Reihenfolge der Initialisierung ist implizit. In initialiser Liste, die Sie haben, um explizit ausgewiesene Bestell - und Compiler warnt der Reihenfolge der Initialisierung, wenn Sie die Bestellung falsch.
Vom standard:
Wenn man die Reihenfolge falsch in der Liste, GCC beschweren:
Nutzen initialiser-Listen ist vielleicht eine Frage des Geschmacks - die Liste ist explizit, in der Regel in der Quell-Datei. In-class ist implizit (wohl), und ist in der Regel in der header-Datei.