2009-10-28 11 views
6

Podczas pracy nad istniejącą biblioteką natknąłem się na dziwne użycie destruktora. Destruktor przydzielonego do stosu wektora stl był wywoływany jawnie, gdy jego przypadek może wymagać ponownego użycia tego obiektu. Te obiekty wektorowe są nieznacznie dostosowaną wersją klasy wektorowej stl, które mają wyspecjalizowaną metodę clear. W ciele destruktora istnieją dwa wywołania metod: clear(), _Tidy().Obiekt przydzielony do stosu w C++, jawne wywołanie destruktora

Próbowałem wymyślić dobry powód, dla którego ten destruktor jest wywoływany, a nie tylko clear, ale jestem na stracie. Ktoś rzuca światło na to, dlaczego to może być dobry pomysł?

+0

Czy możesz podać próbkę kodu, wektorów i jak się nazywa? –

+3

Co robi funkcja _Tidy()? – Brian

+0

Pokaż nam, w jaki sposób utworzono wektor. – sbi

Odpowiedz

1

To zdecydowanie nie jest dobry pomysł. Każda operacja na obiekcie po uruchomieniu destruktora powoduje niezdefiniowane zachowanie.

+0

A raczej po zakończeniu destruktora?Przypuszczam, że może to być poprawne, jeśli skonstruujesz inną instancję w tym samym miejscu z nowym miejscem docelowym, zanim zrobisz cokolwiek innego z instancją i zanim zniknie z zakresu. – UncleBens

+0

A operacje te obejmują automatyczne wywoływanie dtora na końcu zakresu. – sbi

+0

@UncleBens: nie, jak tylko uruchomi się destruktor, powinieneś rozważyć, że twój obiekt już nie istnieje ... spróbuj użyć funkcji wirtualnych z destruktora klasy bazowej, która faktycznie używa pamięci przydzielonej sterty pochodnej klasy ... zobacz co miałem na myśli :) ? –

5

Czy ta klasa może używać jakiegoś rodzaju metody placement new? To jedyny raz, kiedy widzę wyraźne destruktory w użyciu.

+0

Pokonaj mnie, gdy będę pisać. ;) – John

1

Być może oryginalny koder dbał o to, gdzie w pamięci zostały przydzielone obiekty.

Następnie destruktor musi być wywołany jawnie, zgodnie z this discussion.

+0

Co prawdopodobnie ma miejsce, ponieważ dyskusja dotyczy wektora przydzielonego do stosu. –

5

Duży wektor?

Dziki domysł ... kiedy clear() nazywany jest zwykle opróżniany, ale pamięć nie jest zwolniona. Dlatego istnieje wzór, aby opróżnić wektor do ponownego użycia i wyczyścić przydzieloną pamięć.

Być może oryginalny autor nie znał wzorca i próbował pozbyć się przydzielonej pamięci w tym nikczemnym stylu. (Myślę, że _Tidy zwalnia przydzieloną pamięć)

+0

Wektory różnią się rozmiarem, ale nie są erupcyjnie duże. Chciałbym poznać oryginalnych autorów na ten temat, i mam nadzieję, że to była tylko błędna dealokacja pamięci. – Colin

+0

Moje pierwsze pytanie dotyczy takich sytuacji: Co to za komentarz do odprawy? – sbi

9

clear() nie gwarantuje zwolnienia przydzielonej pamięci w wektorze; _Tidy() w implementacji MSVC faktycznie zwolni tę pamięć, więc prawdopodobnie została wykonana jako optymalizacja.

To zła rzecz, ale można to zrobić legalnie (bez niezdefiniowanego zachowania), o ile pamięć jest ponownie wykorzystywana przez obiekt tego samego typu (ignorując kwalifikatory cv), który zajmuje dokładnie całe miejsce :

T automatic; 
automatic.T::~T(); 
new (&automatic) T(); 

Sekcja 3.8.7 normy C++ opisuje ten scenariusz użycia i wyjaśnia, w jaki sposób jest legalny; zawiera nawet przykład podobny do powyższego.

Powiązane problemy