C++: Sollte ich initialisieren Zeiger-Mitglieder zugeordnet sind, die im Konstruktor Körper auf NULL?
Angenommen ich habe:
//MyClass.h
class MyClass
{
public:
MyClass();
private:
Something *something_;
}
//MyClass.cpp
MyClass::MyClass()
{
something_ = new Something();
}
Sollte ich initialisieren something_ auf NULL (oder 0) im Konstruktor mit Initialisierungsliste den Konstruktor MyClass? Oder ist das nicht nötig, denn ich bin mir zuweisen, um es in den Körper des Konstruktors? Was ist die empfohlene Praxis?
- Warum nicht einfach den Zeiger initialisieren in den ersten Platz?
MyClass::MyClass() : something_(new Something())
- Oh, ist das die beste Vorgehensweise?
- Immer lieber die Initialisierung der Zuweisung im Konstruktor Körper. Und verwenden Sie ein smart-pointer wie
shared_ptr
oderscoped_ptr
anstatt einer nativen Zeiger so, dass die Bereinigung erfolgt automatisch, auch im Fall von Ausnahmen. - Also, wenn something_ werden nur intern verwendet, die von MyClass, ist es am besten geeignete zu verwenden shared_ptr oder scoped_ptr?
Du musst angemeldet sein, um einen Kommentar abzugeben.
In der Regel nur vergeben, es einmal in der Initialisierungs-Liste oder den Körper, es sei denn, der Körper Initialisierung kann oder kann nicht passieren, oder hat Voraussetzung-code:
: something_(new Something()), somethingElse_(new SomethingElse(something_))...
)new
in einem raw-pointer so tun sollten, einmal, und dann ist es OK, es zu tun in der Initialisierungsliste. Mehr als eine dynamische Zuordnung ist nicht skalierbar in Bezug auf die Richtigkeit Ausnahme, und es ist ein todsicheres Zeichen, dass Sie brauchen, um die Bereitstellung eines einzelnen-Verantwortung-Ressourcen-manager-Klasse.Generell - nicht. Aber wenn irgendwo in Ihrem Konstruktor-Zeiger wird verwendet, bevor er initialisiert wurde, dann bekommst du ein Undefiniertes Verhalten. Jedoch, die größte problem, das Sie haben, ist, wenn eine Ausnahme geworfen wird, im Konstruktor, der Destruktor nicht aufgerufen wird. Also stellen Sie sich vor, Sie haben zwei Zeiger auf Objekte und die Zuweisung der das erste Objekt, das erfolgreich ist, während die zweite Zuweisung schlägt fehl, in diesem Fall werden Sie am Ende mit ein Ressourcen-Leck. Dieses Problem kann gelöst werden durch die Verwendung von "smart" - Zeiger. Aber in diesem Fall werden Sie initialisiert werden Initialisierung der Liste, und wenn Sie nicht wollen, um einen Wert zuweisen, um Sie zweimal, dann sind Sie besser Speicher drin anstatt im Konstruktor Körper.
Nicht notwendig, vor allem, wenn Sie sofort initialisieren im Konstruktor Körper, aber wenn die Initialisierung ist nicht so offensichtlich, warum dann nicht NULL ist, es zu vermeiden, zufälligen Zugriff auf nicht initialisierte variable.
crazy bug hunting
- definitiv. Ich bin jetzt auf der Jagd nach einer Ressource-Leck (ein Windows-Benutzer-Objekt), und den meisten ärger machennew
Anrufe in der Initialisierungsliste: es gibt kein vorher/nachher in den "atomaren" Welt der Initialisierer-Listen.