N
theliquidwave schrieb:
Zum iterieren: Folgendes Beispiel ist korrekt?
Nein, du greifst auf den ungültigen Iterator zu. Wenn ein Element gelöscht wird, erhöhst du den Iterator nicht, also zeigt it immer noch auf das gleiche Element.
Aber noch was Allgemeines: Ich persönlich bin immer sehr vorsichtig, wenn es um manuelle Speicherverwaltung, C-Strings und ähnlichen Low-Level-Angelegenheiten geht. Ich kapsle solche Dinge meistens, um mit ihnen normal programmieren zu können. Normal heisst Wertsemantik und RAII, man muss nicht explizit freigeben oder sowas. Zwei delete s vor einem erase() sind schon etwas heikel, vor allem wenn man einige Zeit später wieder etwas erweitern möchte.
Zum Beispiel ist dein Code auch nicht exceptionsicher.
char *pszKey = new char[strlen(pszName) + 1];
strcpy(pszKey, pszName);
CBla *pBla = new CBla;
Wenn hier der Konstruktor von CBla oder der new -Operator eine Exception wirft, hast du ein irreversibles Memory Leak. Du sagst jetzt vielleicht, der Konstruktor wirft nichts. Aber mit grösster Wahrscheinlichkeit wirst du eben nicht an diesen Fall denken, wenn du in einem Monat die Klasse CBla plötzlich umgestaltest.
Im Weiteren kannst du deine std::map so nicht kopieren, ohne undefiniertes Verhalten zu riskieren. STL-Algorithmen sind auch gefährlich, weil sie von Wertsemantik ausgehen und Sequenzen umordnen können (ist bei assoziativen Containern nicht sehr relevant, aber allgemein). Zusammengefasst kannst du dir einige Probleme einhandeln, an die du gar nicht denkst. Wenn du vielleicht ein paar Mal einen Nachmittag lange wegen ungültiger Zeiger oder Memory Leaks debuggst, lernst du moderne C++-Konzepte wie RAII zu schätzen.
Gibt es überhaupt einen Grund, wieso du dynamische Speicherverwaltung brauchst? Ist CBla polymorph?
theliquidwave schrieb:
Edit @ Nexus: Kann es sein, dass dein Beispiel dann fehlschlagen würde? Ich dachte das Ende der Map verändert sich, wenn ein neues Item eingefügt oder ein anderes gelöscht wird, bei deinem wird aber immer auf das gleiche Element verwiesen (beim Vergleich in der for-Schleife).
Hm. Bei std::vector dürfte man das sicher nicht machen, aus dem erwähnten Grund. Ich bin mir nicht sicher, was der Standard darüber sagt, aber da andere Iteratoren in assoziativen Containern gültig bleiben, könnte das auf end() ebenfalls zutreffen.
Allerdings würde ich es nicht drauf ankommen lassen. Eigentlich ist das it = map.begin(), end = map.end; it != end lediglich eine blöde Angewohnheit von mir für reine Iterationsschleifen. Und auch da ist der Performancegewinn fragwürdig. Vielleicht sollte ich mir das wieder abgewöhnen, würde auch den Code um einiges schöner machen.