008
29.08.2008, 02:51 Uhr
0xdeadbeef
Gott (Operator)
|
Es handelt sich dabei um eine Funktionsvorlage, d.h., für jeden Typ, mit dem du sie benutzt, wird eine entsprechende Funktion erstellt, ja. Es wird ja bei jedem Typ das gleiche gemacht, deswegen macht es wenig Sinn, sich da mit zwanzigtausend Einzelfunktionen rumzuschlagen.
Übrigens hab ich da nicht richtig aufgepasst, eigentlich müsste das
C++: |
template<typename T> log_class &operator<<(T const &data) { for(std::list<ostream*>::iterator i = streams_.begin(); i != streams_.end(); ++i) { **i << data; }
return *this }
|
heißen. Die for-Schleife geht durch alle registrierten ostreams durch, und schreibt was auch immer übergeben wurde da rein. streams_ ist eine Liste, streams_.begin() und streams_.end() sind Iteratoren, die auf den Anfang der Liste bzw. hinter das Ende zeigen; i läuft von einem zum anderen. Du kannst dir Iteratoren ein bisschen wie Zeiger vorstellen, sie implementieren jedenfalls eine vergleichbare Schnittstelle. *i gibt dir das, worauf i zeigt, und da das ein Zeiger ist (ostreams sind nicht kopierbar), muss der noch dereferenziert werden, bevor man da reinschreiben kann - deshalb **i.
Du könntest auch einen std::vector<ostream*> streams_ benutzen (oder ein Array, und die Speicherverwaltung von Hand machen; aber das wäre unnötig kompliziert) und
C++: |
for(int i = 0; i < streams_.size(); ++i) { *streams_[i] << data; }
|
schreiben, aber ich finde eine Liste hier sinnvoller.
++i ist im Zusammenhang mit Iteratoren schneller als i++, weil bei komplexen Datentypen für das Postinkrement eine Kopie angefertigt werden muss, was beim Präinkrement nicht der Fall ist. Es ist deshalb eine gute Angewohnheit, wo sowohl ++i als auch i++ funktionieren, ++i zu schreiben.
Was die mit << übergebenen Elemente angeht, jedes << bedeutet einen weiteren Funktionsaufruf. <<-Operatoren geben, wenn man es richtig macht, das ostream-Objekt wieder zurück, um diese Notation zu ermöglichen - im Grunde ist
C++: |
std::cout << "foo" << "bar";
|
das selbe wie
C++: |
std::cout << "foo"; std::cout << "bar";
|
...nur halt kürzer. -- Einfachheit ist Voraussetzung für Zuverlässigkeit. -- Edsger Wybe Dijkstra |