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

Wskaźnik do obiektu w dwóch kontenerach i usuwanie tego obiektu

Ostatnio zmodyfikowano 2013-09-03 13:44
Autor Wiadomość
Virpi
Temat założony przez niniejszego użytkownika
Wskaźnik do obiektu w dwóch kontenerach i usuwanie tego obiektu
» 2013-09-01 20:54:28
Krótki i treściwy problem. W uproszczeniu, mam dwie klasy CGameObject i CFuel. CFuel dziedziczy po CGameObject. Mam w programie 2 kontenery:
C/C++
std::vector < CGameObject *> FGameObjects;
std::vector < CFuel *> FFuel;

W pierwszym trzymam wszystkie obiekty typu CGameObject, bo przez polimorfizm rysuję je na ekranie, a w drugim tylko paliwa. Paliwa dodaję w programie tak:
C/C++
CFuel * paliwo = new CFuel( pos.first, pos.second, value );
FGameObjects.push_back( paliwo );
FFuel.push_back( paliwo );

W pewnym miejscu programu mogę usunąć obiekt CFuel, jeśli najechał na nie samochod:
C/C++
for( unsigned int i = 0; i < FFuel.size(); i++ )
{
    if( FFuel[ i ]->checkCollision( FCar ) )
    {
        delete FFuel[ i ];
        FFuel[ i ] = NULL;
    }
}

A później jeszcze w tej samej pętli w grze mam rysowanie obiektów na ekranie:
C/C++
for( unsigned int i = 0; i < FGameObjects.size(); i++ )
{
    if( FGameObjects[ i ] != NULL )
         FGameObjects[ i ]->draw( FGame->GameWindow );
   
}

I otrzymuję AccessViolation. Wydaje mi się, że jeżeli ustawiłem wcześniej po usunięci obiektu wartośc wskaźnika do niego na NULL, to to, na co wskazuje on będąc w drugim kontenerze też wynosi NULL, więc przy rysowaniu ten wskaźnik powinien zostać pominięty .... Czy dobrze to rozumiem? Jeśli nie, to jest jakiś sprytny sposób, na usunięcie tego wskaźnika z drugiego kontenera(nie wiedząc przecież, na jakiej jest on pozycji)?
P-91402
DejaVu
» 2013-09-01 21:08:31
W grach najlepiej oznaczyć obiekt flagą, że ma on zostać zniszczony. Obiekty z ustawioną flagą 'zniszczony' pomijasz, a po wyświetleniu sceny i wykonaniu wszelkich innych algorytmów robisz dodatkową pętlę, która kasuje obiekty z ustawioną flagą 'zniszczony'.

/edit:
Poza tym błędem u Ciebie jest to, że wpychasz do dwóch kontenerów jeden wskaźnik. Kasując obiekt w jednym kontenerze powinieneś również go skasować w drugim. W przeciwnym wypadku po wykonaniu operacji delete wszelkie zapisane wskaźniki na konkretny usunięty obiekt są nieprawidłowe i nie można się do nich odwoływać, a Ty temu obecnie nie zapobiegasz.
P-91404
DejaVu
» 2013-09-01 21:13:30
Dodam jeszcze, że jeżeli masz potrzebę trzymania wskaźnika w kilku kontenerach to powinieneś użyć boost::shared_ptr lub std::shared_ptr (jeżeli używasz kompilatora i bibliotek dla C++11).
P-91406
b00rt00s
» 2013-09-03 13:41:23
A ja dodam od siebie, że jeśli postanowisz używać std::shared_ptr w połączeniu z polimorfizmem, to może Cię zainteresować rzutowanie wskaźników dzielonych. Generalnie polecam również przeczytanie:
http://en.cppreference.com/w​/cpp/memory
http://en.cppreference.com/w​/cpp/memory/shared_ptr
P-91469
pekfos
» 2013-09-03 13:44:20
Co do problemu: wystarczy, że usuniesz także wskaźnik z FGameObject.
P-91470
« 1 »
  Strona 1 z 1