C ++ Konstruktoren Spaß - Konstruieren Foo mit einer Kopie von sich selbst

8

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.]

    
anon 24.02.2010, 19:45
quelle

4 Antworten

12

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. :)

    
GManNickG 24.02.2010, 19:47
quelle
5
%Vor%

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:

%Vor%

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;)

    
AndiDog 24.02.2010 19:58
quelle
3

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:

%Vor%     
meagar 24.02.2010 19:52
quelle
0

Verwendet Foo nicht einen standardmäßigen intrinsischen Konstruktor, wobei die Initialisierungsliste diesen Standardkonstruktor automatisch aufruft, um das Objekt zu initialisieren?

    
Chris Dennett 24.02.2010 19:48
quelle

Tags und Links