kurze frage zu Containern



  • CStoll schrieb:

    Krux schrieb:

    ok wäre schön zu wissen, was ich denn dann überhaupt übergebe.
    Ist das ein funktionspointer inklusive argumente (Funktionspointer stehen in meinem buch irgendwie nicht drin)

    Nein, das ist ein temporär erzeugtes Objekt. Das ganze ist etwa äquivalent zu Partikel tmp(mx,xy,0,-3);pl.push_back(tmp); nur mit dem Unterschied, daß das Objekt keinen Namen bekommt (das ist aus deiner Sicht egal, erleichtert aber dem Compiler mögliche Optimierungen).

    Partikellist pl;
    {
        Partikel tmp;
        pl.push_back(tmp);
    }
    
    pl.//mache irgendwas mit dem letzten objekt von pl
    

    müsste dann ja auch funktionieren
    erzeut der Container dann intern eine Kopie?

    Edit:
    ok jetzt ist alles klar
    pl.push_back(Partikel(1,2,3,4))
    erstellt also ein Partikel kopiert ihn und zerstört den zuerst erstellten dann wieder.



  • Krux schrieb:

    erzeut der Container dann intern eine Kopie?

    jup



  • jetzt hab nich noch eine Frage:

    ich hab meine Liste an Partikeln, und die wird immer durchiteriert. Jedes Partikel hat eine gewisse lebensdauer, und wenn die Abgelaufen ist, das muss der Partikel weg. genau da ist mein Problm:

    Partikellist::iterator pos;
    
    for (pos = pl.begin(); pos != pl.end(); pos++ ){
        if(pos->update(dt))
            pos->draw(kreis);
        else{
            cout << "Jetzt wird gelöscht" << endl;
            pl.erase(pos);
        }
    }
    

    jetzt kommt direkt nach der Ausgabe "jetzt wird gelöscht" ein segmentation fault, und das Programm schmiert ab. Wie lösche ich richtig aus einer Liste?



  • ein erase in einer liste invalidiert den iterator auf das element, das gelöscht wird. erase gibt aber den iterator auf das nächste element zurück. also einfach:

    pos = li.erase(pos);
    

    dein code könnte übrigens noch aussagekräftiger sein, wenn du remove_if verwenden würdest:

    struct NotUpdatable
    {
      bool operator () (Particle &p) const
      {
        if (p.update())
        {
          p.draw();
          return false
        }
        return true;
      }
    };
    
    //...
    li.remove_if (NotUpdatable());
    


  • sorry, hatte vergessen zu sagen, dass update ein bool zurückliefert, das sagt, ob das objekt weiter existieren soll. Ist vieleicht nicht optimal, aber ok.
    wenn ich jetzt

    pos = li.erase(pos);
    

    benutze, überspringe ich dann nicht ein Objekt?



  • ja. nutze besser remove_if, wenn es geht. andernfalls lass pos++ im for-kopf weg und bau es in den if(pos->update()) zweig ein.
    /edit: ps es hat sich eingebürgert, ++pos anstelle von pos++ zu verwenden, was gewisse vorteile bietet.



  • gewisse vorteile? welche denn?

    und was ist wenn ich continue einbaue, dann müsster der doch nicht pos++ durchführen oder?

    Edit, ich hab mir grad mal continue genauer angeschaut (habs noch nie sinnvoll vverwenden können), und es geht nicht.



  • Krux schrieb:

    gewisse vorteile? welche denn?

    ein temporäres objekt weniger, das erzeugt wird. kann geschwindigkeitsvorteile bringen (wenn exzessiv genutzt), schadet auf jedenfall nicht.

    und was ist wenn ich continue einbaue, dann müsster der doch nicht pos++ durchführen oder?

    Edit, ich hab mir grad mal continue genauer angeschaut (habs noch nie sinnvoll vverwenden können), und es geht nicht.

    continue weist ja nur den nächsten schleifendurchlauf an. aber warum jetzt nicht einfach

    for (list<Particle>::iterator pos = foo.begin(); pos != foo.end(); )
       {
          if (pos->update())
          {
             pos->print();
             ++pos;
          }
          else
          {
             pos=foo.erase(pos);
          }
    

    oder
    pos=--foo.erase(pos);
    oder remove_if (ich lege es dir wirklich ans herz)



  • queer_boy schrieb:

    pos=--foo.erase(pos);

    bei einer einfah verketteten liste? Ich denke nicht.

    queer_boy schrieb:

    oder remove_if (ich lege es dir wirklich ans herz)

    ja vieleicht, wenn ich es verstehen würde.



  • Krux schrieb:

    queer_boy schrieb:

    pos=--foo.erase(pos);

    bei einer einfah verketteten liste? Ich denke nicht.

    einfach verkettet? woher hast du das? immerhin verwendet list bidirektionale iteratoren..


Anmelden zum Antworten