std::<list> als dyn.Array, Destructor Mehrfachaufruf (?!)
-
Hallo.
Ich erstelle 25 Instanzen (A) einer Klasse innerhalb einer Funktion, und schiebe sie in eine verkettete Liste einer anderen Klasse (B).
Anschließend werden 18 Instanzen dieser Klasse (B) wieder innerhalb einer Funktion erstellt und ebenfalls in eine Liste einer wiederum anderen Klasse (C) geschoben.
Nun wird ja jedesmal beim Verlassen einer Funktion der Destruktor einer erstellten Instanz aufgerufen. Beim Aufrufen der zweiten Funktion wird sogar nicht mal mehr ein Konstruktor der (A)-Instanzen aufgerufen, sondern nur noch der Destructor von (A), weil ja die (B) Instanzen ja beim Verlassen der Funktion wieder gelöscht werden.
Der statische Zähler innerhalb von A zählt jedenfalls -450 Instanzen.
Frage: Imo wegen oben logisch, aber (hehe) ist das gut oder schlecht?
Ich finde die arbeit mit Listen angenehmer als dyn. erzeugte Arrays auf dem Heap, da ich später Instanzen von A innerhalb B hin und herschiebe oder gar lösche.
An sich läuft alles wie erwünscht, nur daß der Destruktor eben mehrfach aufgerufen wird bringt mich ein wenig durcheinander!
-
normalerweise bist *du* derjenige, der sich darum kümmern muss, dass für jede instanz der destruktor einmal aufgerufen wird.
aber in deinem konkreten fall, vermute ich einfach einmal, dass du vergessen hast, den statischen zähler auch im copy-konstruktor hochzuzählen.
ohne code ist das aber allerhöchstens ein blick in die glaskugel.
-
Beitrag wurde von heise kopiert!
Bitte löschen!
-
MOMENT !!! Hier wurde weder kopiert oder eingefügt !!! Den Link würde ich gerne mal sehen !!!
Um das gleich mal klarzustellen! Hatte mich schon wegen der Spam-Beschwerde gewundert.
-
Eigentlich: Danke für die Lorbeeren
fühle mich geehrt, wenn ich mit Heise-Readkteuren auf eine Stufe gestellt werde.So, genug.
aber in deinem konkreten fall, vermute ich einfach einmal, dass du vergessen hast, den statischen zähler auch im copy-konstruktor hochzuzählen.
Ich benutze gar keinen Kopierkonstruktor.
Beispiel:
class c_A{ /* Do something wonderful pls */ }class c_B{ void Init(); list<c_A> m_List; } void c_B::Init(){ for(int i=0;i<25;i++){ c_A A; m_List.pushback(A); } // Lokale Instanz ungültig, der Destruktor wird aufgerufen } // Weiter mit class c_C{/**/};So in etwa sieht das aus. Klasse C spar ich mir.
-
Josizu schrieb:
class c_A{ /* Do something wonderful pls */ }diese klasse hat einen kopierkonstruktor.
class c_B{ void Init(); list<c_A> m_List; }ebenso diese.
void c_B::Init(){ for(int i=0;i<25;i++){ c_A A; m_List.pushback(A); } // Lokale Instanz ungültig, der Destruktor wird aufgerufen }so ist es richtig:
void c_B::Init(){ for(int i=0;i<25;i++){ c_A A; //instanz erstellen m_List.push_back(A); //kopie von A in die liste einfügen //destruktor von A wird aufgerufen (kopie bleibt in der liste) } }da hat die glaskugel tatsächlich voll ins schwarze getroffen

-
Josizu schrieb:
Ich benutze gar keinen Kopierkonstruktor.
Doch, tust du. Die STL-Container arbeiten mit eben diesen.
Was glaubst du passiert den beim pushback?cu André
-
Ähm, wo bitte ist der Unterschied?
mit:
// Lokale Instanz ungültig, der Destruktor wird aufgerufen
meinte ich, daß außerhalb der Klammern die Instanzen gelöscht werden, also der Destruktor automatisch aufgerufen wird...
-
c_A Awird nach *jedem* schleifendurchlauf zerstört, nach dem durchlaufen der schleife gibt es keinec_Asmehr in der funktion.push_back kopiert sich die c_As und speichert intern kopien (kopierkonstruktor). und diese kopien werden erst dann gelöscht, wenn das jeweilige
c_Bobjekt zerstört wird.
-
Mach doch einfach mal einen Test:
Schreib dir eine Klasse in der alles was von C++ defaultmäsig angelegt wird eine Ausgabe erzeugt:
#include <iostream> class Test { public: Test() { std::cout << "Test::Test()"; } Test(const Test&) { std::cout << "Test::Test(const Test&)"; } ~Test() { std::cout << "Test::~Test()"; } Test& operator=(const Test&) { std::cout << "Test& Test::operator=(const Test&)"; } };Und probiere mit dieser mal ein wenig herum. Dann siehst du ziemlich genau was wir meinen...
cu André