Zunächst einmal haben Sie ein Speicherleck. Aber die Frage ist wahrscheinlich nicht so. Nehmen wir an, Sie haben einen Destruktor, der das Array freigibt.
template<typename Type>
class Array {
size_t n;
Type* buff;
public:
Array(size_t n_): n(n_), buff(new Type[n]) {}
~Array() { delete[] buff; }
};
Jetzt dieser bestimmte Code ist absolut sicher. Beim Zuweisen von n_
kann keine Ausnahme ausgelöst werden, die Reihenfolge der Initialisierung ist korrekt und buff
ist der einzige rohe Zeiger in Ihrer Klasse. Wenn Sie jedoch beginnen, Ihre Klasse zu erweitern und weitere Klassen zu schreiben, erhöht sich das Risiko eines Speicherlecks.
Stellen Sie sich vor, dass Sie eine weitere Mitglieder in die class Array
hinzufügen müssen:
template<typename Type>
class Array {
size_t n;
Type* buff;
SomethingElse xyz;
public:
Array(size_t n_): n(n_), buff(new Type[n_]), xyz(n_) {}
~Array() { delete[] buff; }
};
Wenn der Konstruktor von SomethingElse
wirft, der Speicher für buff
zugeordnet wird auslaufen, weil die destructor ~Array()
nie aufgerufen werden.
Moderne C++ ruft Zeiger wie Type* buff
rohe Zeiger, weil Sie sind verantwortlich für das Aufheben von Zuweisungen Lagerung selbst (Ausnahmen zu berücksichtigen) und stellen Tools wie std::unique_ptr
und std::shared_ptr
, die Pflege von Speicher Deallokation automatisch erfolgen kann.
In der modernen C++ Sie Ihre Klasse wie folgt schreiben könnte:
template<typename Type>
class Array {
size_t n;
std::unique_ptr<Type[]> buff;
public:
Array(size_t n_): n(n_), buff(new Type[n_]) {}
};
Hinweis das Fehlen eines destructor. Die unique_ptr
kümmert sich um den Anruf delete
für Sie.
Beachten Sie auch, keine Abhängigkeit von den Teilnehmern in der Initialisierungsliste (einfach new Type[n_]
statt new Type[n]
Schreiben macht den Code robuster)
Gut für den Anfang haben Sie keinen Destruktor, und das könnte zu einem Speicherverlust führen –
@ArnavBorborah aber ist das das einzige * unsichere * Ding? – Loay