Iterator auf 0 setzen
-
Hallo!
Ich habe in meiner Klasse eine Methode, um alle Elemente einer STL-Liste
zu löschen. Gleichzeitig wollte ich den Iterator auf 0 setzen, um bei
einem folgendem Zugriff auf die Liste einen Segfault zu verhindern.
Jedoch akzeptiert der Compiler das Setzen auf 0 nicht.bool cConfigFile::deleteAll() { m_Configuration.clear(); m_Iter = 0; return true; }Der Compiler meldet:
no match für »operator=« in »((cConfigFile*)this)->cConfigFile::m_Iter = 0«
m_Configuration ist die STL-Liste, und m_Iter der Iterator. Beide sind Member
der Klasse cConfigFile.
-
mase schrieb:
...Gleichzeitig wollte ich den Iterator auf 0 setzen, um bei
einem folgendem Zugriff auf die Liste einen Segfault zu verhindern...Also auch/gerade der Zugriff auf 0 erzeugt einen SegFault.
Das wirst Du also sowieso nicht verhindern können, dass der User darauf zugreift - evtl. mit einer eigenen Iteratorklasse, die ein "gültigKennzeichen" mitführt, das sie vor jedem Zugriff abfragt. Aber das kostet immens Performance und hilft auch nur bedingt. Wenn nämlich der Iterator ungültig ist, weil der Container manipuliert wurde, bekommt der Iterator das nicht mit und das Kennzeichen nützt auch nichts. Hier müsste man eine Verknüpfung zwischen Container und Iterator schaffen, mit der sich ein Iteratr beim Container "anmeldet" und der Container alle registrierten Iteratoren "benachrichtigt", ..... alles keine Kandidaten für den Oscar einer der Kategorien "Performance", "Schnell gemacht" oder "Entkopplung" ...Ich wüsste jetzt nicht, wie man am Iterator selbst festmachen könnte, dass er auf etwas Ungültiges zeigt/ungültig ist - bestenfalls auch end() eines Containers, aber auch da muss der Anwender den Container kennen und gezielt darauf abfragen...
Gruß,
Simon2.
-
Dann muss ich praktisch bei allen Zugriffsmethoden eine .empty() Prüfung
machen, und ggf. einen leeren String (Liste speichert nur Strings)
zurückliefern.
-
mase schrieb:
Hallo!
Ich habe in meiner Klasse eine Methode, um alle Elemente einer STL-Liste
zu löschen. Gleichzeitig wollte ich den Iterator auf 0 setzen, um bei
einem folgendem Zugriff auf die Liste einen Segfault zu verhindern.
Jedoch akzeptiert der Compiler das Setzen auf 0 nicht.bool cConfigFile::deleteAll() { m_Configuration.clear(); m_Iter = 0; return true; }Der Compiler meldet:
no match für »operator=« in »((cConfigFile*)this)->cConfigFile::m_Iter = 0«
m_Configuration ist die STL-Liste, und m_Iter der Iterator. Beide sind Member
der Klasse cConfigFile.Klar, der Iterator ist kein int ( und auch _KEIN_ Zeiger !) .
Bjarne Stroustrup "Die C++ Programmiersprache 4.Auflage Addison-Wesley 2000" §19.2bool cConfigFile::deleteAll() { m_Configuration.clear(); m_Iter = m_List.end(); // Wenn er über std::list<irgendwas> m_List iteriert. return true; }Aber der Code ist trotzdem verdächtig.
Einen Iterator als member zu deklarieren, ist höchst gefährlich; besonders wenn Du, wie hier offensichtlich, auch noch irgendwo seinen Status nutzt und ihn nicht imemr neu initialisierst!Iteratoren können bei Einfüge/Lösch-Operationen auf dem Container ungültig werden! - Stroustrup a.a.O.
Grüsse
*this
-
mase schrieb:
Dann muss ich praktisch bei allen Zugriffsmethoden eine .empty() Prüfung
machen, und ggf. einen leeren String (Liste speichert nur Strings)
zurückliefern.Will ich so nicht beantworten; poste bitte Code.
Grüsse
*this
-
mase schrieb:
Dann muss ich praktisch bei allen Zugriffsmethoden eine .empty() Prüfung
machen, ...Wenn Du das willst, ja.
mase schrieb:
...
und ggf. einen leeren String (Liste speichert nur Strings)
zurückliefern.Entweder das, oder Du wirfst eine exception (wenn es wirklich eine Ausnahme sein soll und nicht der Regelfall). Vorteil: Du brauchst nicht bei jedem Zugriff von Außen auf einen leeren String zu prüfen.
Mal eine Frage: Welche "Liste" verwendest Du denn ? Selbstprogrammiert oder STL-Container ? Da gibt es nämlich auch "Bereichsprüfung" und ein ausgetüfteltes Iteratorhandling...
Gruß,
Simon2.
-
Ich verwende eine STL-Liste.
Der Iterator wird bei mir bei jedem Ändern der Liste auf .begin() gesetzt.