Der Unterschied zwischen default-initialize und value-initialize in C ++ 03?

8

Ich hatte immer gedacht, dass das Erstellen eines neuen Objekts immer den Standardkonstruktor für ein Objekt aufrufen würde, und ob der Konstruktor explizit oder automatisch vom Compiler generiert wurde, machte keinen Unterschied. Laut dies sehr Antwort geguckt auf eine andere Frage, dies hat sich auf subtile Weise zwischen C ++ 98 und C ++ 03 geändert und funktioniert nun so:

%Vor%

Kann mir jemand sagen:

  1. Warum wurde der Standard geändert, d. h. welchen Vorteil hat dies oder was ist jetzt möglich, was vorher nicht war?
  2. Was genau bedeuten die Begriffe "default-initialize" und "value-initialize"?
  3. Was ist der relevante Teil des Standards?
Mark Ransom 16.08.2011, 20:48
quelle

1 Antwort

2

Ich weiß nicht, was die Gründe für die Änderung (oder wie der Standard vorher war), aber wie es ist, default-initialization ruft entweder einen benutzerdefinierten Konstruktor auf oder macht nichts ( viel Hand-waving hier: Dies wird rekursiv auf jedes Unterobjekt angewendet, was bedeutet, dass die Unterobjekte mit einem Standardkonstruktor initialisiert werden, die Unterobjekte ohne benutzerdefinierte Konstruktoren werden nicht initialisiert bleiben).

Dies fällt in die Bezahlung nur für das, was Sie wollen Philosophie der Sprache und ist kompatibel mit C in allen Typen, die C-kompatibel sind. Andererseits können Sie value-initialization anfordern, und dies entspricht dem Aufruf des Standardkonstruktors für Objekte, bei denen oder auf 0 konvertiert wurde geeigneten Typ für den Rest der Unterobjekte.

Dies ist in §8.5 Initialisierer beschrieben, und es ist nicht trivial, durch zu navigieren. Die Definitionen für nullinitialisieren , default-initialize und value-initialize sind der fünfte Absatz:

  

Um ein Objekt vom Typ T zu initialisieren, bedeutet:

     

- Wenn T ein Skalartyp (3.9) ist, wird das Objekt auf den Wert 0 (Null) gesetzt, konvertiert in T;

     

- Wenn T ein Nicht-Vereinigungsklassen-Typ ist, wird jedes nichtstatische Datenelement und jedes Basisklassen-Unterobjekt auf Null initialisiert;

     

- Wenn T ein Union-Typ ist, wird der erste benannte Datenmember89 des Objekts initialisiert;

     

- Wenn T ein Array-Typ ist, wird jedes Element auf Null initialisiert;

     

- Wenn T ein Referenztyp ist, wird keine Initialisierung durchgeführt.

     

Zur Standardinitialisierung eines Objekts vom Typ T bedeutet:

     

- Wenn T ein Nicht-POD-Klassentyp ist (Klausel 9), wird der Standardkonstruktor für T aufgerufen (und die Initialisierung ist fehlerhaft, wenn T keinen zugänglichen Standardkonstruktor hat);

     

- Wenn T ein Array-Typ ist, wird jedes Element standardmäßig initialisiert;

     

- andernfalls wird das Objekt initialisiert.

     

Um ein Objekt vom Typ T zu value-initialisieren, bedeutet:

     

- Wenn T ein Klassentyp (Klausel 9) mit einem benutzerdeklarierten Konstruktor (12.1) ist, wird der Standardkonstruktor für T aufgerufen (und die Initialisierung ist schlecht ausgebildet, wenn T keinen zugänglichen Standardkonstruktor hat);

     

- Wenn T ein Nicht-Vereinigungsklassen-Typ ohne einen von einem Benutzer deklarierten Konstruktor ist, dann wird jeder nicht-statische Daten-Member und Basis-Klassen-Komponente von T value-initialisiert;

     

- Wenn T ein Array-Typ ist, wird jedes Element initialisiert;

     

- andernfalls wird das Objekt auf Null initialisiert

     

Ein Programm, das eine Standardinitialisierung oder Wertinitialisierung einer Entität des Referenztyps aufruft, ist fehlerhaft. Wenn T ein cv-qualifizierter Typ ist, wird die cv-unqualifizierte Version von T für diese Definitionen von Nullinitialisierung, Standardinitialisierung und Wertinitialisierung verwendet.

    
David Rodríguez - dribeas 16.08.2011, 21:26
quelle