Wywołanie destruktora klasy przez interator.
Ostatnio zmodyfikowano 2011-08-29 15:49
akwes Temat założony przez niniejszego użytkownika |
Wywołanie destruktora klasy przez interator. » 2011-08-29 01:49:26 Więc tak, klasa dziedziczy po std::list. template < class T > void SpellList < T >::Obsluga() { std::list < T >::iterator itr = this->begin(); while( itr != this->end() ) { ( * itr )->Obsluga(); if( !( * itr )->IsLive() ) { itr = erase( itr ); } else itr++; } }
Co zrobić aby wywołać destruktor obiektu na który wskazuje iterator? if( !( * itr )->IsLive() ) { delete( * itr ) itr = erase( itr ); } else itr++;
Nie przeszło :P |
|
DejaVu |
» 2011-08-29 10:11:35 Robisz sobie kuku :) Nie dziedzicz z kontenerów nigdy bo kod się robi mało czytelny. Destruktora nie masz prawa wywoływać samodzielnie, jeżeli kontener nie trzymał wskaźników na obiekty, czyli:
std::list < Element *> lista;
W powyższym przypadku możesz zwalniać sobie elementy na które wskazuje iterator np. tak:
Oczywiście pamięć musi być wcześniej zaalokowana poprawnie. |
|
akwes Temat założony przez niniejszego użytkownika |
» 2011-08-29 14:43:07 Ale ja przetrzymuje wskaźniki. Konkretny przykład z kodu SpellList < spelltx *> Spelllist;
obiekty tworze przez
spelltx * czar = new spelltx( this );
No i spelltx ma w konstruktorze Spelllist.push_back( this );
Wiec jeśli chodzi o wskaźniki to ok :P Wiem żeby nie pakować tam zmiennych automatycznych itd, oraz dla automatycznych nie wywołać destruktora bo wywoła się dwa razy(raz sam i drugi raz po wyjściu z zakresu ważności). Wiec jak dostosować zapis Aby działał :P ? Wcześniej miałem własną listę, ale była wolniejsza.... Tylko przynajmniej usuwała elementy :P Tutaj dostaje komunikat o tym że iterator nie może się dalej iterować... A nic o zakresie ważności dostępu do zmiennej, co więcej! Destruktor jest wywoływany (bo pisze mi słodkie słówka na ekranie z destruktora), a potem wywala się właśnie to z iteratora :P Nie chce usuwać pierwszego tylko wybrany, no nie wiem czy problem jest z samym usuwaniem, czy nie wiem czegoś o liście i usuwam sobie też iterator? A konkretnie "Expression: list erase iterator outside range" |
|
DejaVu |
» 2011-08-29 15:27:54 Dane spod iteratora usuwasz poprawnie, ale nawigowanie iteratorami masz zrealizowane źle.
/edit:
Dodam, że z komunikatu, który otrzymałeś wynika:
a->nastepny = new CObiekt(); delete a; a = a->nastepny;
|
|
akwes Temat założony przez niniejszego użytkownika |
» 2011-08-29 15:34:58 Hm... No domyślam się że tak, ale nie rozumiem, dlaczego skoro kod if( !( * itr )->IsLive() ) { itr = erase( itr ); } else itr++;
Działa poprawnie, i faktycznie, obiekt znika z listy i nie ma żadnych problemów. A kiedy dodam zwalnianie pamięci to mam ten błąd o iteratorze. |
|
DejaVu |
» 2011-08-29 15:38:06 if( !( * itr )->IsLive() ) { delete * itr; itr = erase( itr ); } else itr++; |
|
akwes Temat założony przez niniejszego użytkownika |
» 2011-08-29 15:49:04 @up To samo mam w pierwszym poście :P Dobra to chyba... Nie rozumiem. template < class T > void SpellList < T >::Obsluga() { std::list < T >::iterator itr = this->begin(); int a = 0; while( itr != this->end() ) { if( !( * itr )->IsLive() ) { delete * itr; itr = begin(); } else itr++; a++; } std::cout << "Na liscie masz: " << a << " elementow.\n"; }
Okazuje się że używając tylko delete, elementy z listy również znikają, czyżby delete był przeładowany ? =/ Wiec faktycznie, użycie erase po delete było by nie mądre... Z kolejnych zabaw, ten kod też działa poprawnie i usuwa. template < class T > void SpellList < T >::Obsluga() { std::list < T >::iterator itr = this->begin(); std::list < T >::iterator itr2; int a = 0; while( itr != this->end() ) { if( !( * itr )->IsLive() ) { itr2 = itr; itr2++; delete * itr; itr = itr2; } else itr++; a++; } std::cout << "Na liscie masz: " << a << " elementow.\n"; }
|
|
« 1 » |