Ich habe:
%Vor%An diesem Punkt ist
%Vor%[Diese Frage ergab sich aus einer fehlerhaften ref-counted-Zeiger-Implementierung; Ich hätte schwören können, dass ich dafür gesorgt hätte, dass jeder Zeiger auf etwas Nicht-Null gerichtet war; aber ich endete mit einem Zeiger, der auf etwas NULL zeigte.]
foo
wird vollständig initialisiert, sobald Sie den Hauptteil des Konstruktors eingegeben haben (das ist der garantierte allgemeine Fall; speziell wenn die Initialisierung in der Initialisierungsliste abgeschlossen ist).
In Ihrem Fall erstellen Sie aus einem nicht konstruierten Objekt. Dies führt zu undefiniertem Verhalten nach §12.7 / 1 (danke, gf):
Bei einem Objekt des Nicht-POD-Klassentyps (Abschnitt 9) führt die Bezugnahme auf ein nicht statisches Element oder eine Basisklasse des Objekts vor der Ausführung des Konstruktors und nach der Ausführung des Destruktors zu einem nicht definierten Verhalten.
Tatsächlich gibt es dieses Beispiel:
%Vor%Beachten Sie, dass der Compiler nicht benötigt, um eine Diagnose von undefiniertem Verhalten gemäß §1.4 / 1 zu geben. Während ich denke, dass wir alle darin übereinstimmen, wäre es schön, es ist einfach nichts, worüber sich die Compiler-Implementierer kümmern müssen.
Charles weist auf eine Art Schlupfloch hin. Wenn Bar
statischen Speicher hat und wenn Foo
ein POD-Typ ist, wird initialisiert, wenn dieser Code ausgeführt wird. Statisch gespeicherte Variablen werden vor einer anderen Initialisierung auf Null initialisiert.
Dies bedeutet, was auch immer Foo
ist, solange es keinen Konstruktor benötigt, der zur Initialisierung ausgeführt werden soll (d. h. POD sein), werden seine Mitglieder auf Null initialisiert. Im Wesentlichen werden Sie ein Null initialisiertes Objekt kopieren.
Im Allgemeinen ist jedoch ein solcher Code zu vermeiden. :)
Dies ruft den Kopierkonstruktor von foo
auf und kopiert so von einem nicht initialisierten Objekt. Dies führt zu undefiniertem Verhalten, außer Sie haben einen Kopierkonstruktor implementiert, der diesen speziellen Fall behandelt, zum Beispiel:
Aber dieser spezielle Fall wird normalerweise für andere Zwecke verwendet, wie billige Kopien von Strings (wenn eine String-Klasse verwendet wird). Versuchen Sie also nicht, diesen Spezialfall auszunutzen;)
Eine leicht erweiterte Version Ihres Codes scheint darauf hinzuweisen, dass nein, foo
niemals initialisiert wird; Sie scheinen ein undefiniertes Verhalten zu haben. In diesem Beispiel wird "Foo()"
niemals gedruckt. Dies bedeutet, dass keine Instanz von Foo
jemals erstellt wurde:
Verwendet Foo nicht einen standardmäßigen intrinsischen Konstruktor, wobei die Initialisierungsliste diesen Standardkonstruktor automatisch aufruft, um das Objekt zu initialisieren?
Tags und Links c++ constructor