Default, value, und null-Initialisierung Durcheinander
Ich bin sehr verwirrt darüber, Wert- & Standard- & null-Initialisierung.
und vor allem, wenn Sie kick für die verschiedenen standards C++03 und C++11 (und C++14).
Ich bin zitiert und versucht zu verlängern, eine wirklich gute Antwort Wert-/Standard-/Zero - Init C++98 und C++03 hier zu machen, mehr Allgemeine als würde es helfen, eine Menge von Nutzern, wenn jemand helfen könnte, füllen Sie die benötigten Lücken zu haben, die einen guten überblick über das, was passiert, wenn?
Den vollen Einblick durch Beispiele in aller Kürze:
Manchmal die Erinnerung zurück durch den new-operator initialisiert werden, und manchmal ist es nicht abhängig davon, ob der Typ, den Sie newing-up ist ein POD (plain old data), oder wenn es eine Klasse, die enthält POD Mitglieder und ist die Verwendung eines compiler-erzeugten default-Konstruktors.
- In C++1998 es gibt 2 Arten der Initialisierung: null- und default-Initialisierung
- In C++2003 eine 3. Art der Initialisierung Wert-Initialisierung Hinzugefügt wurde.
- In C++2011/C++2014 nur Liste-Initialisierung wurde Hinzugefügt, und die Regeln für Wert-/Standard-/null-Initialisierung ein wenig verändert.
Übernehmen:
struct A { int m; };
struct B { ~B(); int m; };
struct C { C() : m(){}; ~C(); int m; };
struct D { D(){}; int m; };
struct E { E() = default; int m;} /** only possible in c++11/14 */
struct F {F(); int m;} F::F() = default; /** only possible in c++11/14 */
In einem C++98-compiler, der sollte Folgendes auftreten:
new A
- unbestimmten Wert (A
ist POD)new A()
- null-initialisierennew B
- Standard-Konstrukt (B::m
nicht initialisiert ist, wirdB
ist nicht-POD)new B()
- Standard-Konstrukt (B::m
ist nicht initialisierten)new C
- Standard-Konstrukt (C::m
ist null initialisiert,C
ist nicht-POD)new C()
- Standard-Konstrukt (C::m
ist null initialisiert)new D
- Standard-Konstrukt (D::m
nicht initialisiert ist, wirdD
ist nicht-POD)new D()
- Standard-Konstrukt? (D::m
ist nicht initialisierten)
In ein C++03-konforme compiler, die Dinge sollten funktionieren etwa so:
new A
- unbestimmten Wert (A
ist POD)new A()
- Wert initialisierenA
, die null-Initialisierung, da es ein POD.new B
- default-initialisiert (BlätterB::m
initialisierten,B
ist nicht-POD)new B()
- Wert initialisiertB
dem null-initialisiert alle Felder, weil seine default-ctor compiler generiert, im Gegensatz zu Benutzer-definiert.new C
- default-initialisiertC
fordert die default-ctor. (C::m
ist null initialisiert,C
ist nicht-POD)new C()
- Wert initialisiertC
fordert die default-ctor. (C::m
ist null initialisiert)new D
- Standard-Konstrukt (D::m
nicht initialisiert ist, wirdD
ist nicht-POD)new D()
- Wert initialisiert D?, das ruft die default-ctor (D::m
ist nicht initialisierten)
Kursive Werte und ? sind Unsicherheiten, bitte helfen Sie, um dies zu korrigieren 🙂
In eine C++11-konformer compiler, die Dinge sollten funktionieren etwa so:
??? (bitte helfen Sie, wenn ich starten Sie hier es wird sowieso schief gehen)
In einer C++ - 14-konforme compiler, die Dinge sollten funktionieren etwa so:
??? (bitte helfen Sie, wenn ich starten Sie hier es wird sowieso schief gehen)
(Entwurf basiert auf Antwort)
new A
- default-initialisiertA
compiler-gen. ctor, (leavsA::m
nicht initialisierten) (A
ist POD)-
new A()
- Wert initialisiertA
, die null-Initialisierung-seit 2. Punkt in [dcl.init]/8 -
new B
- default-initialisiertB
compiler-gen. ctor, (leavsB::m
nicht initialisierten) (B
ist nicht-POD) new B()
- Wert initialisiertB
dem null-initialisiert alle Felder, weil seine default-ctor compiler generiert, im Gegensatz zu Benutzer-definiert.new C
- default-initialisiertC
fordert die default-ctor. (C::m
ist null initialisiert,C
ist nicht-POD)new C()
- Wert initialisiertC
fordert die default-ctor. (C::m
ist null initialisiert)new D
- default-initialisiertD
(D::m
nicht initialisiert ist, wirdD
ist nicht-POD)new D()
- Wert initialisiertD
fordert die default-ctor (D::m
ist nicht initialisierten)new E
- default-initialisiertE
fordert die comp. gen. ctor. (E::m
nicht initialisiert ist, E ist nicht-POD)new E()
- Wert initialisiertE
, die null-initialisiertE
seit dem 2. Punkt in [dcl.init]/8 )new F
- default-initialisiertF
fordert die comp. gen. ctor. (F::m
nicht initialisiert ist, wirdF
ist nicht-POD)new F()
- Wert initialisiertF
, die default-initialisiertF
seit dem 1. Punkt in [dcl.init]/8 (F
ctor Funktion ist Benutzer-sofern Sie für die Benutzer-erklärt und nicht explizit vorgegeben oder gelöscht " auf seiner ersten Erklärung. Link)
- es gibt eine gute Erklärung gibt es hier: en.cppreference.com/w/cpp/language/default_constructor
- Soweit ich sagen kann, es gibt nur einen Unterschied zwischen C++98 und C++03 in diesen Beispielen. Das Problem scheint zu sein, beschrieben in N1161 (dort sind die späteren überarbeitungen des Dokuments) und CWG DR #178. Die Formulierung muss geändert werden, in C++11 durch neue Funktionen und eine neue Spezifikation der POD, und es wieder in C++ - 14 aufgrund von Mängeln in der C++11-Wortlaut, aber die Auswirkungen sind in diesen Fällen nicht geändert.
- Während langweilig
struct D { D() {}; int m; };
Wert sein kann, einschließlich in der Liste.
Du musst angemeldet sein, um einen Kommentar abzugeben.
C++14 gibt an, die Initialisierung von Objekten erstellt, die mit
new
in [expr.neu]/17 ([expr.neu]/15 in C++11, und der Hinweis war kein Hinweis, sondern normative text damals):Default-Initialisierung ist definiert in [dcl.init],/7 (/6 in C++11, und der Wortlaut an sich hat die gleiche Wirkung):
Damit
new A
allein verursachtA
s default-Konstruktor aufgerufen wird, die nicht initialisiertm
. Unbestimmten Wert. Sollte das gleiche fürnew B
.new A()
interpretiert nach [dcl.init]/11 (/10 in C++11):Und nun überlegen [dcl.init]/8 (/7 in C++11†):
Daher
new A()
wird auf null initialisiertm
. Und das sollte äquivalent sein fürA
undB
.new C
undnew C()
wird default-initialisiert das Objekt erneut aus, da der erste Punkt aus dem letzten Angebot gilt (C ist eine vom Benutzer bereitgestellte default-Konstruktor!). Aber, klar, jetztm
ist die Initialisierung im Konstruktor in beiden Fällen.† Gut, dieser Absatz hat leicht unterschiedliche Formulierungen in C++11, die nicht verändern das Ergebnis:
struct A { int m; }; struct C { C() : m(){}; int m; };
zu unterschiedlichen Ergebnissen führen, und was sind die Ursachen m initialisiert werden, in den ersten Platz. Ich öffnete ein eigener thread für das experiment, das ich Tat, und ich Schätze Ihre Eingabe, es zu klären. Dank stackoverflow.com/questions/45290121/...Folgende Antwort reicht die Antwort https://stackoverflow.com/a/620402/977038, die würde dienen als eine Referenz für C++ 98 und C++ 03
Zitiert die Antwort
Hinzugefügt.
C++11 (In Bezug auf n3242)
Initialisierungen
8.5 Initialisierungen [dcl.init] gibt an, dass eine variable POD oder POD nicht kann initialisiert werden, entweder als Klammer-oder-gleich-Initialisierer, die entweder verspannt-init-Liste oder Initialisierer-Klausel insgesamt bezeichnet als Klammer-oder-gleich-Initialisierer oder mit ( expression-list ). Bisherige C++11, nur (expression-list) oder Initialisierer-Klausel unterstützt wurde, obwohl Initialisierer-Klausel stärker eingeschränkt war dann das, was wir haben, in C++11. In C++11, Initialisierer-Klausel unterstützt jetzt verspannt-init-Liste abgesehen von assignment-expression als in C++03. Die folgende Grammatik beschreibt die neuen unterstützten Klausel, wo das Teil ist Fett ist neu in der C++11 standard.
Initialisierung:
Klammer-oder-gleich-Initialisierung
( expression-list )
Klammer-oder-gleich-Initialisierung:
= Initialisierer-Klausel
verspannt-init-Liste
Initialisierer-Klausel:
assignment-expression
verspannt-init-Liste
Initialisierer-Liste:
Initialisierung-clause ...opt
Initialisierer-Liste , Initialisierer-clause ...opt**
verspannt-init-Liste:
{ Initialisierer-Liste ,opt }
{ }
Initialisierung
Wie C++03, C++11 noch unterstützt drei form initialisieren
Hinweis
Initialisierer Typ:8.5.5 [dcl.init] _zero-initialize_
Durchgeführt in folgenden Fällen
2. Initialisierung Typ: 8.5.6 [dcl.init], _default-initialize_
Durchgeführt in folgenden Fällen
3. Initialisierung Typ: 8.5.7 [dcl.init] _value-initialize_
So zusammenfassen