2016-12-15 1 views
5

Im Wesentlichen, wenn ich mehrere Instanzen einer neuen Klasse erstellen, muss ich den Destruktor für jede Instanz aufrufen, oder wird es aufrufen, sobald jede Instanz zu zerstören (Ich entschuldige mich, wenn ich vage/falsche Begriffe verwende, Konstruktoren/Destruktoren sind Konzepte, die ich noch nicht vollständig verstehe).Muss ich jede Instanz der neuen Klasse zerstören?

Um genauer zu sein, das ist ein Code, mit dem ich arbeite (ich muss mich wieder entschuldigen, wenn der Stil schlecht ist, hatte ich eine Idee für ein Schulproblem und wollte den Code schnell runter).

Also um der Frage willen, nehme an, dass diese Schleife dreimal durchlaufen wird. Muss ich den Destruktor von "account" nur einmal aufrufen, um alle drei Instanzen des neuen Accounts zu löschen, oder wird ein Call die anderen beiden verlassen? Ist das überhaupt eine gute Übung?

Edit: Ich bemerkte, dass einige meiner Post abgeschnitten wurde, so fügte ich die letzten Zeilen hinzu, aber die Leute haben bereits dieses Problem angesprochen. Der Grund, warum ich ein Benutzer bin, ist rein, weil die Aufgabe es vorschreibt; Ehrlich gesagt verstehe ich nicht den Sinn, sie in diesem Moment zu benutzen, aber ich nehme an, dass sie irgendwann nützlich werden. Ich sollte auch hinzufügen, dass die dynamische Speicherzuweisung auch in der Zuweisung verwendet werden soll.

+2

Verwenden intelligente Zeiger (dh 'shared_ptr' /' make_shared' oder 'unique_ptr' /' make_unique') und nicht die Mühe machen schließen Sie über das Löschen ' neue Instanzen. –

+4

Wie immer: Jedes 'neue' braucht genau ein' delete' und jedes 'neue []' genau ein 'delete []'. Allerdings brauchen Sie grundsätzlich nie "neu" und "neu" noch seltener. –

+4

Die eigentliche Frage ist, warum Sie Zeiger zu Beginn verwenden. Bist du aus Java gekommen, wo alle Objekte mit 'new' erstellt wurden? Ihr Array von "account" -Objekten könnte nur tatsächliche account-Objekte * speichern. –

Antwort

5

Destruktoren werden automatisch und Sie in der Regel nicht befürchten es es sei denn Sie Speicher sind die Zuweisung mit new dynamisch genannt.

In diesem Fall werden Sie, wenn Sie delete für jeden zugewiesenen Speicher verlangen brauche ich keine Mehr.

Beachten Sie, dass wenn Sie ein Array mit new [] sind Zuteilung, werden Sie delete[] für desallocation verwenden:

int *a = new int[10]; // allocating an array of 10 integers 

//... 

delete[] a; // release memory 

In modernen C++, sollten Sie verwaltet Zeiger betrachten, die die Arbeit für Sie tun wird. Etwas wie:

while(read >> f >> l >> t >> s >> sta >> acct >> bal) 
{ 
    cout << "test" << endl; 
    ptr[i] = std::make_unique<account>(f,l,t,s,sta,acct,bal); 
    ptr[i]->printcontents(); 
    cout << "test" << endl; 
    i++; 
    cout << i << endl; 
} 

Hier std::make_unique wird wieder ein std::unique_ptr, die auf dem zugehörigen Speicher löschen rufen, wenn sie zerstört.


Letzter Punkt: Sind Sie sicher, dass Sie wirklich Zeiger brauchen?Hart von Ihrem Beispiel zu sagen, aber je nach Nutzung Objekte erstellen können Sie auch statisch zugeordnet:

while(read >> f >> l >> t >> s >> sta >> acct >> bal) 
{ 
    cout << "test" << endl; 
    ptr[i] = account(f,l,t,s,sta,acct,bal); 
    ptr[i].printcontents(); 
    cout << "test" << endl; 
    i++; 
    cout << i << endl; 
} 
+0

Um ein wenig mehr Kontext zu geben, soll dies Teil eines Bankprogramms sein, wobei ich ein Array von Zeigern zu Kontoobjekten verwende, die Kontoinformationen (Name, Kontonummer usw.) speichern. Zunächst erklärte ich Konto * ptr [10] und versuchte Elementfunktion der Klasse Konto zuzugreifen (Account.h ist enthalten), wie diese ptr [i] -> setacctnum (acct); , aber das hat das Programm zum Absturz gebracht. Ich verstehe nicht, warum das nicht funktioniert hat, aber da bin ich jetzt. –

+0

Das Deklarieren von 'account * ptr [10]' erstellt ein Array von ** nicht initialisierten ** Pointern für Account-Objekte. Deshalb ist Ihr Programm abgestürzt: Sie haben versucht, Methoden auf den baumelnden Zeigern aufzurufen. Sie sollten in Erwägung ziehen, Zeiger zu vermeiden und 'account ptr [10]' zu deklarieren: Sie können auf Mitgliedsfunktionen mit Aufrufen wie 'ptr [i] .setacctnum (acct);' zugreifen (beachten Sie das '.' anstelle von' -> ') da 'ptr [i]' jetzt ein Objekt anstelle eines Zeigers ist. Wenn Sie wirklich Zeiger benötigen, betrachten Sie 'std :: unique_ptr' – wasthishelpful

3

Jeder new sollte mit einem delete

balanaced werden Wenn Sie ein Array von Zeigern haben, und new jeder Zeiger, dann würden Sie zu delete jede Instanz benötigen.

Wenn Sie auf der anderen Seite new ein Array von Objekten, können Sie dann delete [] das gesamte Array.

Als Nebenpunkt, für den Code anstelle der Verwendung der ptr (die Sie haben uns nicht gesagt, die Details, man denke nur an eine std::vector<account> und unter Verwendung push_back dann wird es automatisch die Größe je nach Bedarf statt ptr[i] = new....

1

Im Allgemeinen müssen Sie jede Instanz, die Sie erstellen löschen. Genau wie Sie das tun, hängt das ein bisschen ... aber die einfache Daumenregel:

Für jede Verwendung von new muss es eine Verwendung von delete sein.

Für jede Verwendung von new[] muss delete[] verwendet werden.

Wenn Sie die Instanz von einer automatischen Deklaration abrufen, müssen Sie nichts tun, da sie mit ihrem Stack-Frame zerstört wird. aber wenn du es erschaffen hast, zerstörst du es.

1

Wie andere erwähnt haben, wenn Sie new verwenden, dann Sie delete benötigen. Ihr wahres Problem ist jedoch konzeptionell. Sie stellen eine gute Frage, die new und delete periphere sind.

Die normale Verwendung von Destruktoren, mehr als 99,5 Prozent der Zeit, besteht darin, dass der Compiler sie automatisch aufruft. (Die 0,5 Prozent Ausnahme ist abstruse Wir brauchen nicht zu befürchten, dass gerade jetzt..) Mit diesem Code-Fragment

Bedenken Sie:

int n = 5; 
    { 
    int m = 2; 
    ++m; 
    n *= m; 
    // The variable m is automatically destructed here. 
    } 
    // Here, n == 15. 

Sehen Sie, wie das funktioniert? Der Destruktor von m wird automatisch aufgerufen, wenn m das Ende seiner Lebensdauer erreicht, was (weil m nicht mit new gemacht wurde) am Ende des Blocks geschieht, in dem m instanziiert wird.

Natürlich m ist ein int, so dass ihr destructor nichts tut (oder, wenn Sie es vorziehen, m keine destructor hat). Andere Typen, die Sie selbst definieren, wie Ihr Typ account, können Destruktoren haben. Der Destruktor ist automatisch aufgerufen gegen ein einzelnes Objekt in dem Moment, dass das einzelne Objekt, eine Instanz von account, das Ende seiner Lebensdauer erreicht.

NEUE UND LÖSCHEN

Also, was hat das mit new und delete zu tun? In meinem Codefragment habe ich new nicht verwendet. Daher wurde die Lebensdauer meines Objekts von den umgebenden Klammern kontrolliert.

In Ihrem Code-Fragment, das hast du new verwenden. Daher wird die Lebensdauer Ihres Objekts durch Ihre Verwendung von delete gesteuert.

Natürlich haben Sie vergessen, delete zu verwenden, deshalb wurde Ihr Objekt nie zerstört (außer vielleicht, wenn Ihr ganzes Programm beendet wird).

Andere haben festgestellt, dass moderne C++ verbesserte Alternativen zu new bietet, die Sie in den meisten Fällen verwendet werden soll. Sie können ihre Antworten für diese lesen. Allerdings mechanisch, ist es immer noch sehr hilfreich zu verstehen, was schlicht new tut und wie delete Paare mit ihm.

HANDBUCH INVOCATION DER DESTRUCTOR

Sie an Sicherheit grenzender Wahrscheinlichkeit nicht zu kümmern brauchen, weil die Fälle, in denen ein destructor manuell selten und fortgeschritten sind aufgerufen wird. Grundsätzlich, wenn Sie sich selbst den Speicher verwalten, in dem ein Objekt gespeichert wird (was Sie fast nie tun, aber es gibt seltene Ausnahmen), dann kann der Compiler nicht sagen, wann er zu zerstören ist, also müssen Sie ihm sagen wann. Ein typisch esoterisches Beispiel finden Sie unter this.

0

Nur Zeiger müssen die destructor nennen, sie zu löschen oder das Programm

Verwandte Themen