Du bist nicht angemeldet.

Werbeanzeige

1

30.08.2011, 22:03

Expression: list iterators incompatible

huhu,

bei meinem kleinen PacMan clon is mal wieder was schief gegangen :/ wenn ich kompeliere geht ein Dialog auf und

Zitat

Expression: list iterators incompatible
steht da drin

player.h

C-/C++-Quelltext

1
list<Block*>::iterator it;


player.cpp - hier bei passiert es!

C-/C++-Quelltext

1
2
3
4
5
       for(it = g_pMap->GetBlockList().begin(); it != g_pMap->GetBlockList().end(); it++)
    {
        if(g_pCollision->Intersects(p_playerSprite->GetRect(), (*it)->GetRec()))
            cout << "BOOM";
    }



und hier noch die Map.h

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
class Map : public TSingleton<Map>
{
public:

    list<Block*> GetBlockList();

private:
    list<Block*> blockList;
}


was kann ich dagegen tun?

drakon

Supermoderator

Beiträge: 6 516

Wohnort: Schweiz

Beruf: Entrepreneur

  • Private Nachricht senden

2

30.08.2011, 22:10

Der Fehler kommt, wenn du einen Iterator auf die eine Liste hast und denn den mit einem Iterator einer anderen einsetzt.
z.B sowas hier:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <iostream>
#include <list>

using namespace std;

int main()
{
    list<int> l1;
    list<int> l2;

    list<int>::iterator it = l1.begin();

    if(it == l2.begin())
        cout << "foo";
}


Da scheint also irgendwo sonst etwas schief zu laufen.

David Scherfgen

Administrator

Beiträge: 10 355

Wohnort: Hildesheim

Beruf: Wissenschaftlicher Mitarbeiter

  • Private Nachricht senden

3

30.08.2011, 22:13

Übrigens: Deine GetBlockList()-Methode erzeugt eine Kopie Deiner Liste und gibt die Kopie zurück.
Für sowas benutzt man Referenzen!

drakon

Supermoderator

Beiträge: 6 516

Wohnort: Schweiz

Beruf: Entrepreneur

  • Private Nachricht senden

4

30.08.2011, 23:03

Finde ich nicht unbedingt, zumindest keine nicht konstante. Sonst kann man die Liste ja gleich öffentlich machen.

//EDIT
Also ich würde hier eine konstante Referenz der Liste zurückgeben oder das ganze gleich intern machen, da man sonst ja schon recht etwas über die interne Funktionsweise der Map freigibt, was nicht ganz dem Sinn von Information Hiding entspricht.

5

31.08.2011, 06:31

hmm ich muss zugeben das ich etwas überfordert bin, ... ich versteh das problem immer noch nich so ganz
ich hab genau den iterator zugewiesen den ich auch in der schleife benutze, ich hab den sogar noch eindeutiger umbenannt damit ich nich doch zufällig nen falschen nehme, aber dem scheint nich so zu sein :/

drakon

Supermoderator

Beiträge: 6 516

Wohnort: Schweiz

Beruf: Entrepreneur

  • Private Nachricht senden

6

31.08.2011, 11:39

Nein. Das sind eben nicht die gleichen Listen. Da du eine Kopie zurück gibst wird da eine andere Liste erstellt bei jedem Aufruf von GetBlockList().
Du machst semantisch das hier:

C-/C++-Quelltext

1
for(it = l1.begin(); it != l2.end(); it++){...}

NachoMan

Community-Fossil

Beiträge: 3 889

Wohnort: Berlin

Beruf: (Nachhilfe)Lehrer (Mathematik, C++, Java, C#)

  • Private Nachricht senden

7

31.08.2011, 11:54

Das Problem ist, dass du beim Erstellen des Iterators eine Kopie von der Liste hast. Beim vergleich hast du eine andere Kopie.
Damit:

C-/C++-Quelltext

1
list<Block*>& GetBlockList();

ist das Problem erstmal gelöst.

Übrigens verwendest du viel zu viele Singletons. Versuchs mal ganz ohne :thumbsup:

Edit: Drakon hats ja schon gepostet -.- Ich bin echt noch zu müde.
"Der erste Trunk aus dem Becher der Erkenntnis macht einem zum Atheist, doch auf dem Grund des Bechers wartet Gott." - Werner Heisenberg
Biete Privatunterricht in Berlin und Online.
Kommt jemand mit Nach oMan?

8

31.08.2011, 15:20

ah ja ok so gehts, danke :)

aber wieso keine singeltons? im buch spricht man eigentlich eher positiv von ihnen

ridens

Frischling

Beiträge: 47

Beruf: Freiberuflicher Entwickler

  • Private Nachricht senden

9

31.08.2011, 18:27

ah ja ok so gehts, danke :)

aber wieso keine singeltons? im buch spricht man eigentlich eher positiv von ihnen


Im Buch wirds im Grunde sogar genannt, aber ignoriert. Singletons sind global. Das ist dir sicher daran aufgefallen, dass du außerhalb der Klassendefinition die Membervariable, die das Singleton speichert, initialisieren musst. Das ist natürlich schon der erste Grund, global ist böse und gehört verboten.

Soweit ich es verstanden habe, ist das große tatsächliche Risiko von Singletons aber, wenn mehr als nur ein Singleton existiert und diese miteinander interagieren. Speziell beim Löschen der Singletons. Globale Variablen werden in einer Reihenfolge gespeichert und rückwärts wieder freigegeben (ähnliches Prinzip wie beim Stack). Wenn jetzt Singleton A allerdings bei seinen Aufräumarbeiten Singleton B braucht, dieses aber schon gelöscht ist, kann das böse Folgen haben. Soweit mein Verständnis des Problems. Ich habe mir dieselbe Frage gestellt und auf stackoverflow einen Thread dazu gefunden, das ist hier meine Quelle :)

10

31.08.2011, 18:43

ah ok na wenn das so is dann werd ich bei meinen nächsten projekten unterlassen

was ich aber fast schade finde weil ich das mit den singeltons schon irgentwie toll fand :/
ging ja darum das man wenn man nur ein objekt von einer klasse brauch aber halt in mehreren verschiedenen Klassen, man nicht die ganze zeit das object bzw. nen zeiger davon rumschieben muss ... ich fand das eigentlich sehr angenehm

Werbeanzeige