Elemente eines Vektors löschen
-
Aus einem Vector solltest du sowieso - wenn überhaupt - nur selten Elemente, die nicht am Ende sind löschen. Wenn du diese Eigenschaft öfter benötigst, solltest du einen anderen Container verwenden (std::deque oder std::list).
Was spricht gegen einen:
std::vector <A> v;Der räumt schon von selbst auf. Ein std::vector <A*>, dem du mit new erstellte Objekte hinzufügst, ist imho auch nicht exception-safe. Da müsstest du Smart Pointer benutzen oder die Lösung von Boost Pointer Container
Gruß
Don06
-
bei einem std::vector<A*> ist die reihenfolge in der du delete und erase ausführst egal. der vector kümmert sich nicht darum, wie du deine A* verwaltet hast und entfernt nur einen zeiger aus seinem bestand, bei dem völlig egal ist, wo er hinzeigt. delete auf der anderen seite gibt nur den speicher frei und kümmert sich nicht darum, was mit den zeigern passiert.
sauberer ist natürlich die variante erst aus dem vector entfernen und dann löschen, da man dann keinen datenmüll in dem vector liegen hat.aber wie Don06 schon schrieb: überlegt dir genau, ob ein vector<A*> das ist, was du willst.
-
Okay, danke.
Aus einem Vector solltest du sowieso - wenn überhaupt - nur selten Elemente, die nicht am Ende sind löschen.
Wieso das? Nimmt jetzt nicht automatisch, wenn ich z.B. das 2te Element im Vector lösche, das 3te Element den Platz ein?
-
dosunmu schrieb:
Aus einem Vector solltest du sowieso - wenn überhaupt - nur selten Elemente, die nicht am Ende sind löschen.
Wieso das? Nimmt jetzt nicht automatisch, wenn ich z.B. das 2te Element im Vector lösche, das 3te Element den Platz ein?
Das Dritte wird auf den Platz des Zweiten kopiert, das Vierte auf das Dritte, das Fünfte auf das Vierte, das Sechste auf das Fünfte usw. usf.
Das ist ein enormer Aufwand. Laufzeit O(n).Bei einer std::list werden einfach die Elemente umgehängt. Vom Ersten kommt man dann direkt zum Dritten und umgekehrt. Das Zweite wird einfach aus der Kette herausgenommen. Laufzeit O(1).
Grüssli
-
Dravere schrieb:
Bei einer std::list werden einfach die Elemente umgehängt. Vom Ersten kommt man dann direkt zum Dritten und umgekehrt. Das Zweite wird einfach aus der Kette herausgenommen. Laufzeit O(1).
Jedoch geht diese Schnelligkeit auf Kosten des Random Access. Je nach Situation eignet sich deshalb ein anderer Container.
-
Don06 schrieb:
Was spricht gegen einen:
std::vector <A> v;Also es soll ja Klassen geben, die bestimmte Pointer beinhalten - und den Speicherbereich im DTor löschen... Da fällt mir sofort so was ein, wie HANDLEs, die man noch mal braucht, um zu sagen ob da schon iwas abgelaufen ist oder nicht...
Oder wie machst du so was?
Aber da sollte wahrscheinlich auch so was, wie std::auto_ptr reichen ^^
bb
//edit: ne, ich glaub, ich hatte da nen denkfehler - es muss nen purer ptr sein glaube ich... ist schon spät ^^
-
auto_ptr kann man nicht in Container packen. Falls man einen Smartpointer braucht wäre evtl. boost::shared_ptr die richtige Wahl. Noch bessert wäre da aber vielleicht einer der boost::ptr_container.
-
Ich hab ehrlich gesagt noch nie einen Container mit Zeigern gefüllt... Wozu braucht man das? Der Sinn eines Containers ist ja gerade, dass man die Speicherverwaltung nicht selber handzuhaben braucht, was durch eigene Pointer wieder zunichte gemacht würde. Und wenn man Klassen hat, die intern Zeiger besitzen und diese auch ordentlich wieder freigeben, hat man auch kein Problem, diese als Elemente in Containern zu verwenden.
-
Nexus schrieb:
Wozu braucht man das?
Ein Container von polymorphen Objekten.
-
7H3 N4C3R schrieb:
Ein Container von polymorphen Objekten.
Okay, das hat mich jetzt überzeugt. Ich bin eben selber noch nicht in die Situation gekommen, da ich noch nicht sehr viel mit Polymorphie zu tun hatte, und deshalb hab ich daran gar nicht gedacht
