Podwójne wywołanie destruktora

0
#include <iostream>
#include <string>

using namespace std;


class a{
private:
	int ab;
public :
	a(){ab=55;}
	~a(){cout<<"kasuje!\n";}
};

int main(){
	a obj;
	cout<<"Już nie jesteś potrzebny!";
	obj.~a();
	return 0;
} 

Utworzyłem obiekt obj. Potem obiekt nie jest mi potrzebny więc chcę uruchomić destruktor aby go zniszczyć i zwolnić pamięć.

Dlaczego chwilę potem,(na końcu działania programu) uruchamia się znowu destruktor obiektu obj? Jak przed chwilą go zniszczyłem??

0

Destruktorów nie uruchamia się ręcznie.

0

Mógłbyś dać jakiś powód czemu tego nie robić?

1

Dlaczego chwilę potem,(na końcu działania programu) uruchamia się znowu destruktor obiektu obj? Jak przed chwilą go zniszczyłem??

Właśnie dlatego.
Trzeba dodać, że destruktor niczego nie niszczy, a jedynie sprząta po obiekcie. Samo "niszczenie" dla zmiennych na stosie jest automatyczne i wtedy właśnie wywoływany jest destruktor.

0

Tworząc obiekt na stosie to kompilator / runtime / system operacyjny decyduje kiedy zniszczyć obiekt. I ty tworząc obiekt na stosie właśnie zrzucasz tą odpowiedzialność na niego.

0

Mógłbyś dać jakiś powód czemu tego nie robić?

Dlatego, że jest on wywoływany automatyczne podczas niszczenia obiektu. Generalnie destruktor wywołujesz w sposób jawny tylko dla obiektów, które zostały stworzone operatorem placement new, czyli:

char tab[ sizeof(a) ];

a* obj = new(tab) a; //<--- to tylko tworzy obiekt, nie przydziela pamięci

...

obj->~a();
0

Mam klasę Potworek{...}, Bohater{...}
I klasę Gra{...},w której tworzę 10 obiektów klasy Potworek.
Następnie bohater atakuje i zabija czwarty obiekt klasy Potworek.
JAK skasować/zwolnić pamięć po obiekcie nr4...?? Nie jest mi on już potrzebny! (reszta Potworków jest)
Nie chcę czekać na koniec programu...

0

A kto mówi, że obiekt stworzony na stosie zostanie usunięty dopiero na koniec programu?

Jeżeli chcesz jawnie zarządzać czasem życia obiektów to używaj operatorów new oraz delete.

0
Rev napisał(a)

A kto mówi, że obiekt stworzony na stosie zostanie usunięty dopiero na koniec programu?

Jeżeli chcesz jawnie zarządzać czasem życia obiektów to używaj operatorów new oraz delete.

możesz utworzyć obiekt na stosie i usunąć go nie czekając do zakończenia programu. Trza się babrać z zasięgami ale nie trzeba stosować do tego new czy delete (no dobra chyba, że uczepić się tego JAWNIE, wtedy chyba nie ma innego wyjścia :) )

#include <iostream>

using namespace std;

class MyClass {
    public:
        MyClass() { std::cout << "MyClass::MyClass();\n"; }
        ~MyClass() { std::cout << "MyClass::~MyClass();\n"; }

};

int main()
{
    {
        MyClass obj;
    }
    return 0;
}

@Rev oczywiście to nie jest kontrprzykład, a raczej zobrazowanie twojej wypowiedzi.

0

Samo "niszczenie" dla zmiennych na stosie jest automatyczne
Przy czym słowo „niszczenie” jest bardziej obrazowe niż dosłowne. Dokładniejszym słowem byłoby „zapomnienie”.
Przykładowo, pola zniszczonego obiektu wcale nie są zerowane (chyba że robi to destruktor, ale po co). To tylko fragment pamięci którą obiekt zajmował jest „zwalniany”, czyli od tej pory będzie mógł zostać zajęty przez jakąś inną zmienną.

1 użytkowników online, w tym zalogowanych: 0, gości: 1