2013-01-10 26 views
14

Ich habe erst gestern erfahren, dass die Angabe von Parametern für Initialisierungslistenelemente optional ist. Wie lauten die Regeln für das, was in diesem Fall passiert?Standardwerte in C++ - Initialisierungslisten

Im folgenden Beispiel wird ptr auf 0 initialisiert, auf "false" umgestellt und "Bar default-constructed"? Ich denke, diese Frage ist irgendwie redundant, weil es in Initialisierungslisten wenig Sinn hätte, wenn nicht spezifizierte Argumentwerte == undefiniertes Verhalten.

Kann ich auch auf den Abschnitt des C++ - Standards hingewiesen werden, der das Verhalten im Fall von Initialisierungslistenelementen angibt, die keine Argumente erhalten?

class Bar 
{ 
    Bar() { } 
}; 

class SomeClass; 
class AnotherClass 
{ 
public: 
    SomeClass *ptr; 
    bool toggle; 
    Bar bar; 

    AnotherClass() : ptr(), toggle(), bar() { } 
    // as opposed to... 
    // AnotherClass() : ptr(NULL), toggle(false), bar(Bar()) { } 
}; 
+0

Mögliche Duplikate von [Konstruktorinitialisierungsliste mit leerer Initialisierung] (https://stackoverflow.com/questions/11164394/constructor-initialization-list-with-empty-initialization) – Justin

Antwort

12

Ja, die Elemente werden auf Null bzw. ein standardmäßig erstelltes Objekt initialisiert.

Die C++ 11-Standard spezifiziert dieses Verhalten in 12.6.2/7:

Die Ausdrucksliste oder verspannt-init-Liste in einem mem-Initialisierer verwendet den bestimmten Subobjekt zu initialisieren (oder, im Fall eines delegierenden Konstruktors das vollständige Klassenobjekt) gemäß den Initialisierungsregeln von 8,5 für direkte Initialisierung.

wiederum 8,5/10 lautet:

Ein Objekt, dessen Initialisierer ist ein leerer Satz von Klammern, das heißt,(), Wert initialisiert werden soll.

Paragraph 8.5/7 definiert Wert initialisierten:

auf ein Objekt vom Typ T-Wert initialisieren bedeutet:

  • wenn T ist eine (möglicherweise cv-qualifiziert) Klassentyp (Abschnitt 9) mit einem vom Benutzer bereitgestellten Konstruktor (12.1), dann wird der Standardkonstruktor für T aufgerufen (und die Initialisierung ist schlecht ausgebildet, wenn T keine zugängliche StandardeinstellunghatKonstruktor);
  • wenn T ein (möglicherweise cv-qualifiziert) nicht gewerkschaftlich Klassentyp ist ohne vom Benutzer bereitgestellte Konstruktor, dann das Objekt Null initialisiert und, wenn T der implizit deklarierte Standardkonstruktors nicht-trivial ist, dass Konstruktor wird aufgerufen.
  • Wenn T ein Array-Typ ist, dann wird jedes Element wertinitialisiert;
  • Andernfalls ist das Objekt Null initialisiert.

Und schließlich 8,5/5 definiert Null initialisierten:

auf Null initialisieren, ein Objekt oder Referenz vom Typ T bedeutet:

  • wenn T a ist Skalartyp (3.9), das Objekt wird auf den Wert 0 (Null) gesetzt, der als ein Integralkonstantenausdruck verwendet wird, der in T konvertiert wird;
  • wenn T a (möglicherweise cv-qualifiziert) non-union Klassentyp, wobei jeder nicht-statischen Daten Element und jede Basisklasse Subobjekt ist Null initialisiert und padding wird auf Null initialisiert Bits;
  • Wenn T ein (möglicherweise cv-qualifizierter) Union Typ ist, wird das erste nicht statische Datenelement des Objekts null- initialisiert und das Padding wird auf null Bits initialisiert;
  • Wenn T ein Array-Typ ist, wird jedes Element auf Null initialisiert;
  • Wenn T eine Referenz ist, wird keine Initialisierung durchgeführt.
+0

Ausgezeichnet und detailliert. Genau das, was ich gesucht habe - danke! –

2

Initialisierungen fallen in [dcl.init] (auch bekannt als 8,5)

Punkt 10 sagt:

Ein Objekt, dessen Initialisierer ist ein leeres Klammern, dh(), soll initialisiert werden

Wert Initialisierung ist, einfach gesagt, Standardkonstruktion für Klassen und Null-Initialisierung für Nicht-Klasse-Typen.

6

Im folgenden Beispiel wird PTR 0, wechseln zu falsch und Bar default-konstruiert initialisiert werden?

Ja. Wenn ein Elementinitialisierer mit leeren Klammern in der Initialisierungsliste angezeigt wird, ist das Element initialisiert. Dies bedeutet, dass numerische Typen auf Null, Zeiger auf Null und Klassen mit Standardkonstruktoren, die diesen Konstruktor verwenden, initialisiert werden.

Wenn Sie das Element überhaupt nicht in die Initialisierungsliste aufnehmen, wird stattdessen standardmäßig initialisiert; In diesem Fall. numerische und Zeigertypen werden nicht initialisiert.

Kann ich auch den Abschnitt des Standard-C++ hingewiesen werden, die nicht gegeben ist, Argument, das Verhalten im Fall von Initialisiererliste Artikel besagt?

C++ 11 12.6.2/7 legt fest, dass die Regeln dieselben sind wie bei der direkten Initialisierung.

C++ 11 8.5/16 gibt an, dass das Objekt initialisiert wird, wenn der Initialisierer () ist.

C++ 11 8.5/7 definiert Wert Initialisierung.

Verwandte Themen