Gast Geschrieben 16. April 2008 Geschrieben 16. April 2008 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) { } Zitieren
Klotzkopp Geschrieben 16. April 2008 Geschrieben 16. April 2008 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? Zitieren
Wodar Hospur Geschrieben 16. April 2008 Geschrieben 16. April 2008 #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? Zitieren
Klotzkopp Geschrieben 16. April 2008 Geschrieben 16. April 2008 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. Zitieren
Wodar Hospur Geschrieben 16. April 2008 Geschrieben 16. April 2008 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. Zitieren
Klotzkopp Geschrieben 16. April 2008 Geschrieben 16. April 2008 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] Zitieren
Gast Geschrieben 17. April 2008 Geschrieben 17. April 2008 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.... Zitieren
Empfohlene Beiträge
Dein Kommentar
Du kannst jetzt schreiben und Dich später registrieren. Wenn Du ein Konto hast, melde Dich jetzt an, um unter Deinem Benutzernamen zu schreiben.