Veröffentlicht 16. April 200817 j hi, habe ein kleines problem. habe einen vector<Object*> mit ein paar objekten drinne, den ich gerne nach einem Object (o) durchsuchen, dieses object löschen und aus dem vector entfernen will. hat jemand eine idee? void GarbageCollector::removeObject(Object* o) { }
16. April 200817 j Grundsätzlich geht das mit std::find (oder std::find_if) und std::vector::erase. Woran erkennst du denn das zu löschende Objekt? Nur an seiner Adresse?
16. April 200817 j #include <iostream> #include <vector> #include <string> using namespace std; static vector<string> vec = vector<string>(); void RemoveObject(string str) { for(vector<string>::iterator it = vec.begin();it!=vec.end();it++){ if(str == *it) { vec.erase(it); } } } int main(int argc, char *argv, char **env) { string str = string(" ihr da "); vec.push_back(string(" hallo ")); vec.push_back(str); vec.push_back(string(" have fun ")); for(vector<string>::iterator it = vec.begin();it!=vec.end();it++){ cout << *it << endl; } RemoveObject(str); for(vector<string>::iterator it = vec.begin();it!=vec.end();it++){ cout << *it << endl; } return 0; } Sollte so absolut funktionieren und auch C++ Style sein. Aber wenn ich Garbage Collector lese, willst du dir wirklich einen schreiben? Hast du dir schonmal Smart Pointer angesehn?
16. April 200817 j static vector<string> vec = vector<string>(); Warum global und static? Und der Defaultkonstruktor wird sowieso aufgerufen. for(vector<string>::iterator it = vec.begin();it!=vec.end();it++){ if(str == *it) { vec.erase(it); } }[/code] Undefiniertes Verhalten. Durch den Aufruf von erase wird der Iterator ungültig, den darfst du danach weder inkrementieren noch dereferenzieren. Eigentlich könnte man das ganze auch auf einen Schlag mit std::remove lösen: [code]#include <iostream> #include <vector> #include <string> #include <algorithm> using namespace std; int main(int argc, char *argv, char **env) { vector<string> vec; string str = string(" ihr da "); vec.push_back(string(" hallo ")); vec.push_back(str); vec.push_back(string(" have fun ")); for(vector<string>::iterator it = vec.begin();it!=vec.end();it++){ cout << *it << endl; } vec.erase( remove(vec.begin(), vec.end(), str), vec.end() ); for(vector<string>::iterator it = vec.begin();it!=vec.end();it++){ cout << *it << endl; } } Wenn man nicht direkt nach einem Wert suchen kann, kann man std::remove_if nehmen.
16. April 200817 j Warum global und static? Und der Defaultkonstruktor wird sowieso aufgerufen. Damit die Funktion auf den vector zugreifen kann muss ich irgendeine Lösung finden, bei so einem Beispiel kann es dann auch mal global sein. Static muss glaub ich nicht bei global genutzt werden, war ich mir aber nicht sicher. Undefiniertes Verhalten. Durch den Aufruf von erase wird der Iterator ungültig, den du dandarfst ach weder inkrementieren noch dereferenzieren. Wow das ist mir aber neu, danke für die Info! Sprich ich hab auf einen Iterator eigentlich nur lesend Zugriff oder müsste ihn nach dem Ändern direkt erneut positionieren? Alleine die STL nutzen zu können, wie es soll wird wohl noch sehr sehr viel Übung brauchen.
16. April 200817 j Wow das ist mir aber neu, danke für die Info! Sprich ich hab auf einen Iterator eigentlich nur lesend Zugriff oder müsste ihn nach dem Ändern direkt erneut positionieren?Genau. Zu diesem Zweck gibt std::vector::erase einen Iterator auf das nächste Element zurück, oder end(), wenn das letzte Element gelöscht wurde. Das bedeutet aber, dass man den Iterator nicht im Schleifenkopf inkrementieren darf, weil man sonst ein Element überspringt, oder über end() hinausgeht. Richtig sähe das dann so aus: for(vector<string>::iterator it = vec.begin();it!=vec.end();[b]/*nix*/[/b]){ if(str == *it) { it = vec.erase(it); } else ++it; }[/code]
17. April 200817 j hi, danke für eure antworten, ich könnte mir in den popo beissen. hatte es genau so, nur beim vergleich das * beim iterator vergessen :/ @Wodar Hospur ja smart pointer kenne ich, aber habe mich mit der boost lib noch nicht so befasst und weiss noch nicht genau ob ich sie einsetzen soll....
Archiv
Dieses Thema wurde archiviert und kann nicht mehr beantwortet werden.