Verwirrung mit std::list



  • Wieso funktioniert das:

    std::list<int> intlist;
    intlist.push_back(1);
    intlist.push_back(2);
    intlist.push_back(3);
    intlist.pop_front();
    
    for(std::list<int>::iterator i = intlist.begin(); i != intlist.end(); ++i)
    {
        std::cout<<i<<std::endl; //Gibt 2 und 3 aus
    }
    

    Jedoch nicht das:

    class Foo
    {
      public:
           Foo(int i)
           {
              m_i = i;
           }
    
           int GetI() 
           {
              return m_i;
           }
      private:
           int m_i;
    }
    
    //...
    
    std::list<Foo> foolist;
    foolist.push_back(Foo(1));
    foolist.push_back(Foo(2));
    foolist.push_back(Foo(3));
    
    foolist.pop_front();
    for(std::list<Foo>::iterator i = foolist.begin(); i != foolist.end(); ++i)
    {
        std::cout<<i->GetI()<<std::endl; //Stürzt ab
    }
    

    Ist std::list unfähig benutzerdefinierte Datentypen zu managen?



  • Du greifst in der unteren Schleife auf intlist und nicht auf foolist zu. intlist ist da wahrscheinlich noch leer. Der iterator ist auch falsch. Hier sollte eigentlich ein Compilerfehler kommen.



  • for(std::list<Foo>::iterator i = intlist.begin(); i != intlist.end(); ++i)
    

    Ich hoffe,das ist ein Tippfehler,denn in deinem Programm gibt es kein 'intlist'.



  • Chewbaka schrieb:

    for(std::list<Foo>::iterator i = intlist.begin(); i != intlist.end(); ++i)
    

    Ich hoffe,das ist ein Tippfehler,denn in deinem Programm gibt es kein 'intlist'.

    ja, ist jetzt rauseditiert, ahb einfach copy & paste gemacht. die frage bleibt erhalten.



  • Bei mir geht das



  • TravisG schrieb:

    Chewbaka schrieb:

    for(std::list<Foo>::iterator i = intlist.begin(); i != intlist.end(); ++i)
    

    Ich hoffe,das ist ein Tippfehler,denn in deinem Programm gibt es kein 'intlist'.

    ja, ist jetzt rauseditiert, ahb einfach copy & paste gemacht. die frage bleibt erhalten.

    Probiers doch einfach nochmal und wenns immernoch Probleme gibt bei einem konkreten Beispiel,poste bitte das genaue Beispiel. Das ist nichtmal eine Vollständige Klassendeklaration.



  • Konkretes Beispiel:

    class Particle
    {
    public:
    	Particle(); /* Creates a standard particle which has a lifetime of 1 second,
    				   velocity of 1.0f and 0 friction */
    
    	Particle(float lifetime,float velocity,float friction);
    	~Particle();
    
    	void Update();
    	void Shoot(sf::Vector2f startpos, float angle);
    	void SetAngle(float angle);
    	bool IsAlive();
    
    	sf::Vector2f GetPosition();
    private:
    	float m_lifetime; 
    	float m_velocity;
    	float m_angle;
    	float m_friction;
    
    	//The particle needs to be "emitted" (shot) before it starts to do something
    	bool m_shot;
    
    	sf::Vector2f m_position;
    	sf::Clock m_lifeclock;
    };
    

    Implementationen sollten egal sein.

    class ParticleEmitter
    {
    public:
    	ParticleEmitter();
    	~ParticleEmitter();
    
    	void SetParticleSprite(std::string filename);
    	void SetParticleSprite(sf::Sprite *spr);
    	void SetParticleFriction(float friction);
    	void SetShootingAngle(float angle);
    	void SetPosition(sf::Vector2f pos);
    
    	void Shoot(float angle,float velocity,float lifetime, float friction = 0.0f);
    	void Update();
    	void Draw();
    
    	sf::Vector2f GetPosition();
    private:
    	sf::RenderWindow *m_window;
    	sf::Sprite *m_sprite;
    	sf::Image m_spriteimage;
    	std::list<Particle > m_particles;
    	sf::Vector2f m_position;
    	float m_friction;
    };
    

    In der Methode "Update()":

    void ParticleEmitter::Update()
    {
    	for(std::list<Particle>::iterator i = m_particles.begin(); i!=m_particles.end(); ++i)
    	{
    		if(!i->IsAlive())
    		{
    			m_particles.erase(i);
    		}
    		else
    		{
    			i->Update();
    		}
    	}
    }
    

    Stürzt ab sobald ich nach dem Löschen eines Elements zum Beispiel sowas mache:

    for(std::list<Particle>::iterator i = m_particles.begin(); i!=m_particles.end(); ++i)
    	{
    		m_sprite->SetPosition(i->GetPosition());
    		m_window->Draw(*m_sprite);
    	}
    


  • for(std::list<Particle>::iterator i = m_particles.begin(); i!=m_particles.end();)
        {
            if(!i->IsAlive())
            {
                i = m_particles.erase(i);
            }
            else
            {
                i->Update();
                ++i;
            }
        }
    


  • drakon schrieb:

    for(std::list<Particle>::iterator i = m_particles.begin(); i!=m_particles.end();)
        {
            if(!i->IsAlive())
            {
                i = m_particles.erase(i);
            }
            else
            {
                i->Update();
                ++i;
            }
        }
    

    ah, da fällts mir auf einen schlag auch wie schuppen vom hintern, oder wie das heisst. wieso bin ich nicht früher drauf gekommen?

    edit: ich nehme an erase() gibt einen iterator aufs nächste objekt zurück?



  • TravisG schrieb:

    edit: ich nehme an erase() gibt einen iterator aufs nächste objekt zurück?

    Jap! An so einem Fehler hab ich auch schon mal _ewig_ gehangen. Übrigens finde ich das auch relativ unintuitiv, aber das nur am Rande.


Anmelden zum Antworten