Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

Wywołanie destruktora klasy przez interator.

Ostatnio zmodyfikowano 2011-08-29 15:49
Autor Wiadomość
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.

C/C++
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?

C/C++
if( !( * itr )->IsLive() )
{
    delete( * itr )
    itr = erase( itr );
}
else
     itr++;


Nie przeszło :P
P-40147
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:
C/C++
std::list < Element *> lista;
W powyższym przypadku możesz zwalniać sobie elementy na które wskazuje iterator np. tak:
C/C++
delete * lista.begin();
Oczywiście pamięć musi być wcześniej zaalokowana poprawnie.
P-40154
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

C/C++
SpellList < spelltx *> Spelllist;

obiekty tworze przez
C/C++
// spelltx(spell *);
// Wszystko się dziele w klasie spell.
spelltx * czar = new spelltx( this );

No i spelltx ma w konstruktorze
C/C++
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
C/C++
delete( * itr )
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"
P-40170
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:
C/C++
a->nastepny = new CObiekt();
delete a;
a = a->nastepny; //'a' już nie istnieje, więc nie możesz się dostać do następnego wskaźnika
P-40177
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
C/C++
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.
P-40178
DejaVu
» 2011-08-29 15:38:06
C/C++
if( !( * itr )->IsLive() )
{
    delete * itr;
    itr = erase( itr );
}
else
     itr++;
P-40180
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.

C/C++
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.
C/C++
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";
}
P-40182
« 1 »
  Strona 1 z 1