Virtueller operator++ - möglich?
-
Hallo,
ich habe operator++() bisher immer so gesehen:
class Iterator {
Iterator operator++();
//...
}wenn ich jetzt aber Iterator zu einer pure virtual class mache, meckert der Compiler, weil operator++() ein Objekt zurückgibt.
Kann man die Iterator-Klasse trotzdem virtuell machen?
Vllt darf man bei operator++() auch eine Referenz zurückgeben? Nur habe ich operator++() bisher immer nur mit echten Objekten gesehen! Wie ist denn der Standard?
Danke für Antworten im voraus!
Johannes
-
Beim operator++() geht natürlich eine Referenz. Beim operator++(int) müßte es eine Kopie sein. Normalerweise gibt der operator() auch nur eine Kopie zurück, weil sizeof(Iterator)==sizeof(int) und die Referenz wenn der Compiler den Code nicht sehen würde, was aber eh nicht der Fall ist, vielleicht was langsames machen würde.
-
Virtuelle Funktionen und Iteratoren passen nicht so richtig zusammen. Zumindest nicht, wenn Du "C++"-Iteratoren schreiben willst, weil sie "normal"-kopierbar sein sollten, also ohne Indirektion benutzt werden. Wenn Du die richtigen virtuellen Funktionen aufgerufen haben willst, musst Du mit Indirektion arbeiten -- also mit Zeigern und/oder Referenzen arbeiten.
Auf den Verdacht hin, dass Du schon einmal Java (oder so) programmiert hast: Bei Sprachen wie Java, C#, u.s.w. ist die Indirektion implizit. Damit meine ich, dass eine Variable eines Klassentyps eigentlich immer eine Art Zeiger ist -- also nicht das Objekt selbst sondern nur ein Verweis darauf.
Nichtsdestotrotz kann man mit der "type erasure"-Technik in C++ Iteratoren erstellen, die sich wie "normale" C++-Iteratoren verhalten, aber "intern polymorph" sind. Man kann mit dieser Technik eine Familie von Iterator-Typen erzeugen, die nur über den Element-Typen parametrisiert werden und sonst "Kontainer-agnostisch" sind (anders formuliert: Der Typ eines solchen Iterators ist immer der gleiche, egal über was Du für einen Kontainer du iterierst). Das kann u.U. sehr praktisch sein.
(Andere Beispiele für "type erasure" sind boost::function und boost::any)
Gruß,
SP
-
Danke für die schnellen Antworten. Mit Referenzen ging es, auf type-erasure musste ich zum Glück nicht zurückgreifen

Aber ich habe noch eine Frage: Woher weiß ich, ob eine operator()-Funktion nun eine Referenz oder das Objekt selber haben muss/darf? Gibt es da irgendwo eine Übersicht oder so etwas?
-
voidpointer_ schrieb:
Danke für die schnellen Antworten. Mit Referenzen ging es, auf type-erasure musste ich zum Glück nicht zurückgreifen

Aber ich habe noch eine Frage: Woher weiß ich, ob eine operator()-Funktion nun eine Referenz oder das Objekt selber haben muss/darf? Gibt es da irgendwo eine Übersicht oder so etwas?
Ja nennt sich Hirn

-
voidpointer_ schrieb:
Danke für die schnellen Antworten. Mit Referenzen ging es, auf type-erasure musste ich zum Glück nicht zurückgreifen

Aber ich habe noch eine Frage: Woher weiß ich, ob eine operator()-Funktion nun eine Referenz oder das Objekt selber haben muss/darf? Gibt es da irgendwo eine Übersicht oder so etwas?
-
voidpointer_ schrieb:
Mit Referenzen ging es, auf type-erasure musste ich zum Glück nicht zurückgreifen

Aha. Zeig doch mal ein kleines Beispiel. Klingt nicht so, als hättest Du STL-kompatible Iteratoren geschrieben. Wenn das gar nicht Dein Ziel war (warum nicht?) hättest Du auch eine komplett andere Abstraktion nutzen können.
Gruß,
SP