Codebeispiel sollte Dinge erklären:
%Vor%Offensichtlich sollte pB explizit auf NULL initialisiert werden, um sicher (und klar) zu sein, aber wie es steht, Was ist der Wert von pB nach der Konstruktion von A? Ist es standardmäßig initialisiert (was ist Null?) oder nicht (dh unbestimmt und was auch immer in Erinnerung war). Ich weiß, dass die Initialisierung in C ++ ein paar Regeln hat.
Ich denke, es ist nicht standardmäßig initialisiert; im Debug-Modus in Visual Studio ausgeführt, hat es pB auf 0xcdcdcdcd zeigen - was bedeutet, dass der Speicher wurde neu (auf dem Heap), aber nicht initialisiert. Im Ausgabemodus jedoch zeigt pB immer auf NULL. Ist das nur zufällig und daher nicht verlässlich; oder initiieren diese Compiler es für mich (auch wenn es nicht im Standard ist)? Es scheint auch NULL zu sein, wenn es mit Suns Compiler auf Solaris kompiliert wird.
Ich suche wirklich nach einem bestimmten Verweis auf den Standard, um das eine oder andere zu sagen.
Danke.
Hier ist die relevante Passage aus dem Standard:
12.6.2 Initialisierung von Basen und Mitgliedern [class.base.init]
4 Wenn ein bestimmtes nicht statisches Datenelement oder Die Basisklasse wird nicht von einem Speicher benannt Initialisierungs-ID in der mem-initializer-Liste, dann
- Wenn die Entität eine nicht statische Daten ist Mitglied von (möglicherweise cv-qualifiziert) Klassentyp (oder Array davon) oder eine Basisklasse und die Entitätsklasse Ist eine Nicht-POD-Klasse, wird die Entität standardmäßig initialisiert ( dcl.init ). Wenn die Entität ein nicht statisches Datenelement eines Const-qualifizierten Typs ist, Die Entitätsklasse muss einen vom Benutzer deklarierten Standardkonstruktor haben.
- Andernfalls ist die Entität nicht initialisiert . Wenn die Entität von Const-qualifizierter Typ oder Referenztyp oder eines (möglicherweise cv-quali- fied) POD-Klassenart (oder Array davon), die (direkt oder indirekt) ein Mitglied eines const-qualifizierten Typs, das Programm ist krank- gebildet.
Nach dem Aufruf eines Konstruktors für Klasse X wurde abgeschlossen, wenn ein Mitglied
von X ist in der mem-initializers des Konstruktors, noch
Standard initialisiert oder initialisiert während der Ausführung des Körpers von
der Konstruktor, das Mitglied hat unbestimmter Wert.
Laut C ++ 0x Standard Abschnitt 12.6.2.4, im Fall Ihrer Zeigervariable, wenn Sie es nicht in die Initialisierungsliste aufnehmen und Sie es nicht im Körper des Konstruktors setzen, dann hat es einen unbestimmten Wert. 0xCDCDCDCD und 0 sind zwei mögliche solche Werte, wie auch alles andere. : -)
Ich glaube, das ist ein Artefakt aus den guten alten C-Tagen, in denen man nicht erwarten konnte, was der allokierte Speicher enthält. Als die Standards nach C ++ weiterentwickelt wurden, wurde diese "Konvention" beibehalten. Als die C ++ - Compiler entwickelt wurden, nahmen die einzelnen Autoren es auf sich, dieses Problem zu "beheben". Daher kann Ihre Laufleistung abhängig von Ihrem gewählten Compiler variieren.
Das "0xcdcdcdcd" scheint ein leicht erkennbares Muster zu sein, das beim Debuggen von Code "hilft". Deshalb wird es im Freigabemodus nicht angezeigt.
Ich hoffe, das hat ein bisschen geholfen und viel Glück.
Nicht initialisierte Zeiger können auf alles zeigen. Einige Compiler-Anbieter helfen Ihnen dabei und zeigen auf 0 oder 0xcdcdcdcd oder was auch immer.
Um sicherzustellen, dass Ihr Code sicher und portabel ist, sollten Sie Ihre Zeiger immer initialisieren. entweder auf 0 oder auf einen gültigen Wert.
z.B.
%Vor%oder
%Vor%Wenn Sie Zeiger immer auf 0 initialisieren, ist dies sicher:
%Vor%Wenn Sie sich nicht initialisieren, haben Sie keine Möglichkeit, initialisierte und nicht initialisierte Zeiger voneinander zu unterscheiden.
Abgesehen davon gibt es in C ++ kein solches Schlüsselwort als NULL. Die meisten Compiler definieren NULL als 0, aber sie werden nicht als portabel betrachtet. Der neue c ++ 0x-Standard wird ein neues Schlüsselwort, nullptr, einführen. Wenn das herauskommt, haben wir endlich eine portable Null-Zeiger-Konstante.
Es ist selten, dass ich Ihnen rate, nichts über die Sprache zu lernen, die Sie verwenden, aber in diesem Fall ist es nicht nützlich, ob pB initialisiert wird oder nicht. Initialisiere es einfach. Wenn es automatisch initialisiert wird, optimiert der Compiler die zusätzliche Initialisierung. Wenn dies nicht der Fall ist, haben Sie eine zusätzliche Prozessoranweisung hinzugefügt und eine ganze Reihe potentieller Fehler verhindert.
Nicht initialisierte Zeiger können grundsätzlich einen zufälligen Wert enthalten, obwohl manche Compiler dazu neigen, sie mit 0 oder einem anderen erkennbaren Wert zu füllen, besonders im Debug-Modus.
IMHO ist dies wegen C ++ 's "nicht für das, was Sie nicht verwenden" -Design bezahlen. Wenn Sie es nicht für wichtig halten, muss der Compiler nicht die Kosten der Initialisierung der Variablen für Sie übernehmen. Natürlich, sobald Sie einen zufälligen Zeiger verfolgt haben, finden Sie es vielleicht ratsam, es beim nächsten Mal zu initialisieren ...