2015-02-08 10 views
5

Ich benutze Visual C++ 2013. Wenn die Klasse ein Aggregat ist, ist es Null initialisiert. Wenn es ein Nicht-Aggregat ist, scheint es default-initialisiert und unbestimmt zu sein. Warum das?C++ 14 Uniform Initialisierung auf einem Non-Aggregate

#include <iostream> 

using namespace std; 

class Test_1 
{ 
public: 
    int i; 
    void f(){}; 
}; 

class Test_2 
{ 
public: 
    int i; 
    virtual void f(){}; 
}; 

int main() 
{ 
    Test_1 t1{}; 
    Test_2 t2{}; 

    cout<<t1.i<<endl; //0 
    cout<<t2.i<<endl; //-858993460 

    getchar(); 
} 
+3

Welcher Compiler und welche Version? '{}' sollte eine Wert-Initialisierung für Nicht-Aggregate sein und 't2.i' sollte Null-initialisiert sein, da es keinen vom Benutzer bereitgestellten Konstruktor hat. –

+0

Das führt dazu, dass MSVC, das auf [rextester] gehostet wird (http://rextester.com/runcode), hängen bleibt und dann ähnlichen Müll gibt. Das gleiche gilt für einen anderen [MSVC Online-Compiler] (http://webcompiler.cloudapp.net/). Ich rieche einen Käfer. –

Antwort

4

Wenn Ihr Compiler dies tut, ist es kaputt.

[dcl.init.list]/p3 (Alle Zitate von N4140):

List-Initialisierung eines Objekts oder einer Referenz des Typs T ist wie folgt definiert:

  • Wenn T ein Aggregat ist, wird die Aggregatinitialisierung durchgeführt (8.5.1).
  • Wenn die Initialisierungsliste keine Elemente enthält und T ein Klassentyp mit einem Standardkonstruktor ist, lautet das Objekt value-initialized.
  • [...]

[dcl.init]/p8:

auf ein Objekt der Typwert initialisieren T bedeutet:

  • wenn T ist ein (möglicherweise cv-qualifizierter) Klassentyp (Klausel 9) mit entweder keinem Standardkonstruktor (12.1) oder einem Standardkonstruktor, der vom Benutzer bereitgestellt oder gelöscht wird das Objekt wird standardmäßig initialisiert;
  • wenn T ist ein (möglicherweise cv-qualifiziert) Klassentyp ohne einen vom Benutzer bereitgestellte oder gelöscht Standardkonstruktors, dann ist das Objekt Null initialisiert, und die semantischen Einschränkungen für default-Initialisierung werden überprüft, und wenn T a hat nicht-trivial Standard Konstruktor, das Objekt ist default-initialisiert;
  • Wenn T ein Array-Typ ist, wird jedes Element initialisiert.
  • Andernfalls wird das Objekt auf Null initialisiert.

Test_2 nicht ein Aggregat ist, so sollte t2 gewesen sein Wert initialisiert. Da der Standardkonstruktor von Test_2 nicht vom Benutzer bereitgestellt wird, sollte t2 als erstes null initialisiert werden (wodurch t2.i auf 0 initialisiert wird), und dann wird der Standardkonstruktor ausgeführt.

+4

Value-Initialisierung von nicht-trivialen Klassen ist in der Tat in VC++ gebrochen, und war schon immer. Leider ist trotz der grundlegenden Notwendigkeit der Initialisierungssemantik keine Lösung in Sicht. [Hier] (https://connect.microsoft.com/VisualStudio/feedback/details/746973/incorrect-c-11-value-initialization-for-type-mit-implizit-deklariert-aber-nicht-trivial-default-constructor) ist einer von _many_ eingereicht Fehlerberichte, alle geschlossen als 'aufgeschoben', die ich gesehen habe. [In einigen Fällen ist nicht einmal die Initialisierung der Aggregation korrekt.] (Https://connect.microsoft.com/VisualStudio/Feedback/Details/956553) – ildjarn