ostream mit mehreren targets
-
Hallo, ich will einen Logger schreiben, der genau wie die Standardstreams cout, clog, cerr funktioniert. Der Logger soll konfigurierbar sein, so dass beispielsweise in verschiedene Dateien geschrieben werden kann oder nach stdout, stderr, stdlog, eventuell soll auch in die syslogs geschrieben werden. Also ähnlich wie
class logger : public basic_ostream<char> { list<ostream*> streams; };Allerdings weiss ich nicht wie man die den basic_ostream mit den anderen Stream verknüft. Hat jemand eine Idee?
-
Vll hilft dir das ja weiter:
http://www.c-plusplus.net/forum/viewtopic-var-t-is-116667-and-postdays-is-0-and-postorder-is-asc-and-highlight-is-streambuf-and-start-is-17.htmlbb
-
headmyshoulder schrieb:
Allerdings weiss ich nicht wie man die den basic_ostream mit den anderen Stream verknüft. Hat jemand eine Idee?
Wenn deine Klasse nur ein Logger sein muss und selber gar nicht Streamfunktionalität hat - also je nach Anwendung auf andere Streams zurückgreift - brauchst du ihn auch nicht von
std::basic_ostreamabzuleiten.Praktisch ist es, wenn du die Macht der Polymorphie nutzt, indem du einen Basisklassenzeiger auf
std::ostreamhast. Dann kannst du je nach Anwendung auf einen anderen Stream, der vonostreamerbt, zeigen.class Streamer { public: Streamer(); Streamer(std::ostream* NewStream); ~Streamer(); template <typename T> std::ostream& operator<< (const T& Object); void SetStream(std::ostream* NewStream); void operator= (std::ostream* NewStream); private: std::ostream* MyStream; };Du solltest dir vielleicht auch überlegen, ob die Klasse das Stream-Objekt besitzt, also auch für dessen Löschung zuständig ist, oder ob nur bereits existente Streams übergeben werden. Je nachdem kannst du auch statt Zeigern Referenzen übergeben.
Anwenden kannst du Instanzen von
Streamerganz normal benutzen, wenn du denoperator<<sinngemäss überlädst.int main() { Streamer s; s << "ein Text mit der Nummer " << 43 << " war das." << std::endl; }Wenn mehrere Streams gleichzeitig verwaltet werden sollen, speicherst du deren Zeiger in einer
std::listund iterierst diese beim Zugriff auf die Streams durch (beispielsweise beim Aufruf des <<-Operators).
-
Nexus schrieb:
Wenn mehrere Streams gleichzeitig verwaltet werden sollen, speicherst du deren Zeiger in einer
std::listund iterierst diese beim Zugriff auf die Streams durch (beispielsweise beim Aufruf des <<-Operators).Falls mich nicht alles täuscht, wird er entweder auf die STL-Container verzichten müssen oder auf die Referenzen (und damit nicht um Pointer drum rumkommen ^^)...
bb
-
unskilled schrieb:
Falls mich nicht alles täuscht, wird er entweder auf die STL-Container verzichten müssen oder auf die Referenzen (und damit nicht um Pointer drum rumkommen ^^)...
Und was ist so schlimm daran, Zeiger zu verwenden? Wenn es einen stört, kann man ja die Schnittstelle immer noch mit Referenzen einrichten, sodass man Objekte direkt übergeben kann, anstatt
operator&zu schreiben.Aber das ist dann sowieso wieder davon abhängig, ob die Klasse besitzergreifendes Verhalten hat oder nicht.
-
Ok, Danke erstmal für Eure Antworten.
unskilled schrieb:
Vll hilft dir das ja weiter:
http://www.c-plusplus.net/forum/viewtopic-var-t-is- ....... sc-and-highlight-is-streambuf-and-start-is-17.htmlDas sieht ganz interessant aus und könnte eventuell schon mein Problem lösen.
Nexus schrieb:
Praktisch ist es, wenn du die Macht der Polymorphie nutzt, indem du einen Basisklassenzeiger auf
std::ostreamhast. Dann kannst du je nach Anwendung auf einen anderen Stream, der vonostreamerbt, zeigen.class Streamer { public: Streamer(); Streamer(std::ostream* NewStream); ~Streamer(); template <typename T> std::ostream& operator<< (const T& Object); void SetStream(std::ostream* NewStream); void operator= (std::ostream* NewStream); private: std::ostream* MyStream; };Das wird für eine Liste von Streams problematisch, weil "operator<<" in dem Fall nicht *this zurückgeben kann.