2017-01-26 3 views
1

I Studieren C++ Konzept. Ich bin verwirrt in Konstruktor und Destractor-Konzept. Destruktor wird beim Beenden des Programms vom Compiler implizit aufgerufen. Aber in meinem Programm hat nur Konstruktor aufgerufen.Warum nicht Destructor in C++ aufrufen?

#include <iostream> 
using namespace std; 

class A 
{ 
     int i; 
public: 
     A() 
     { 
       cout<<"Constructor call"<<endl; 
     } 
     ~A() 
     { 
       cout<<"Destructtor call"<<endl; 
     } 
}; 

int main() 
{ 
     A *a = new A(); 
} 

Ausgang:

Constructor call 

Also, ich habe eine Frage: Warum destructor nicht vom Compiler auf Exit-Programm implizit nennen?

+0

"Destructor wird implizit vom Compiler beim Beenden des Programms aufgerufen" ist falsch. –

Antwort

7

Warum Destruktor Aufruf nicht implizit vom Compiler beim Beenden des Programms?

Da dynamisch zugewiesene Objekte nicht automatisch zerstört werden. So wurde die Sprache spezifiziert. Die Verfolgung der Zerstörung dynamischer Objekte würde einen Overhead für Laufzeit und Arbeitsspeicher erfordern.

Lösung: Verlieren Sie keine dynamisch zugewiesenen Objekte.

+0

Danke für die Klärung meiner Zweifel. – rsp

+1

Und verwenden Sie Smartpointer, um den Heapspeicher zu verwalten. RAII und Destruktoren im Allgemeinen sind eine der wichtigsten Funktionen von C++. –

3

Sie erstellen das Objekt dynamisch mit new. Der Destruktor wird nur aufgerufen, wenn der beanstandete Eintrag mit delete gelöscht wird.

Um Speicherverluste zu vermeiden, könnten/sollten Sie Smartpointer wie unique_ptr verwenden.

In jedem Fall wird der Speicher selbst natürlich freigegeben, wenn der Prozess endet.

0

Weil Sie ein Speicherleck haben. Sie dynamisch erstellt ein Objekt mit new, versprechen, dass Sie die Lebensdauer des Objekts verwalten und es später mit delete aufräumen würden. Dann hast du dieses Versprechen gebrochen.

Wenn Sie ein Objekt in der üblichen Art und Weise zu erstellen:

A a; 

dann wird es automatisch für Sie zerstört werden.

2

Der Destruktor wird niemals in Ihrem Code aufgerufen, da das Objekt niemals zerstört wird.

Sie ordnen das A Objekt dynamisch zu und Sie werden es nie freigeben. In delete a; in main() und Sie werden die destructor in Aktion sehen:

int main() 
{ 
    A *a = new A(); 
    delete a; 

    return 0; 
} 
1

In Ihrer Hauptfunktion erstellen Sie eine Zeigervariable, die Sie durch delete a am Ende der Hauptfunktion löschen müssen.

4

Es gibt 2 "Typen" variabler Lebensdauer in C++. Dynamisch und automatisch.

Automatik ist so etwas wie:

void foo() 
{ 
    int i; // automatic storage 
} // destroys i 

Hier finden i den Moment es Rahmen verlässt zerstört werden (nach foo Returns).Sie können diese für sich selbst überprüfen, indem Sie Ihr Objekt eine automatische Lebensdauer machen:

int main() 
{ 
    A a; // calls A's constructor and allocates memory. 
} //calls A's destructor and frees the memory used. 

Sie werden sehen, dass sowohl der Konstruktor und der Destruktor wird aufgerufen.


Die zweite Form ist dynamisch zugeordneter Speicher. Sie können Speicher dynamisch zuweisen, indem Sie new verwenden (wie Sie) und diesen Speicher freigeben, indem Sie delete verwenden. Der Compiler wird nicht dies für Sie tun. Das bedeutet, dass zerstören Ihr Objekt, das Sie sich delete explizit aufrufen müssen:

int main() 
{ 
     A* a = new A(); 
     delete a; // calls A's destructor and frees the memory used. 
} 

Wenn Sie delete nicht nennen (wie Ihr Code), dann in dem Moment das Programm verlässt main der Zeiger a zerstört wird und wir jetzt Habe ein Stück Speicher, dass nichts erreichen kann und damit niemand aufräumen kann (mit delete) was bedeutet, du bist leaking memory.

Moderne Betriebssysteme beanspruchen jedoch automatisch den gesamten Speicher, der vom Programm verwendet wird, sobald das Programm beendet ist, zu diesem Zeitpunkt ist es nicht mehr wichtig. Dies bedeutet, dass Ihr Destruktor nicht so aufgerufen wird, wie Sie gerade gesehen haben.


dynamisch zugewiesenen Speicher ermöglicht es Ihnen, wie die Steuerung der Lebensdauer Ihrer Objekte zu dem Punkt, einige nette Tricks zu tun, wo man sie explizit mit delete selbst zerstören wollen. Das Problem mit der Verwendung new und delete ist, dass es so einfach ist, eine einzige delete zu vergessen, und Ihr Programm wird bereits Speicher auslaufen, weshalb es ratsam ist, weg von dieser Art der Zuweisung zu bleiben.

Wenn aus irgendeinem Grund absolut Sie dynamische Lebensdauer benötigen dann einen intelligenten Zeiger wie std::unique_ptr verwenden, die new und delete für Sie der Moment nennen es den Gültigkeitsbereich verlässt.