Eigenes Endl
-
Ich habe die Klasse logfile von std::ofstream bageleitet und wollte ihr ein
eigenes Endl spendieren.
Ziel des ganzen ist dass der logfile nacher automatische Einrückung
beherrscht, deshalb wollte ich bei jedem Endl ein log << tabs; davor setzen.
Einschneller Hack von mir sieht so aus:class logfile : public std::ofstream { public: logfile(cstring& file) : std::ofstream(file.c_str()) {}; ~logfile(void) { } logfile& Endl(void) { (*this) << std::endl; (*this) << "Worx! "; return (*this); } }; //GEHT std::ostream& endl(std::ostream& o) { if(logfile* l = dynamic_cast<logfile*>(&o)) return l->Endl(); else return o << std::endl; } //GEHT NICHT logfile& endl(logfile& o) { return o.Endl(); }
Eine der beiden Endls ist jeweils ausgeklammert.
Bei der 2. Variante sagt mir der gcc noch:
warning: the address of `logfile& endl(logfile&)', will always be `true'
und im Output steht immer '1' statt einer neuen Zeile + "Worx".Bin ich nur zu übermüdet um zu sehen woran der Fehler liegt oder mache
ich was grundsätzlich falsch? Wie geht das richtig?
-
1. sollte man eigene Streams implementieren indem man seinen eigenen std::stream_buf implementiert
2. kannst du endl so implementieren
struct my_endl { }; std::ostream &operator<<(std::ostream &out,const my_endl &e) { out << "\nhallo welt!"; return out; } my_endl endl() { return my_endl; }
und dann brauchst du noch nichtmal nen eigenen Stream.
-
Geht nicht!
Das Warning bleibt und die Funktionen endl und der Operator werden
nicht mal aufgerufen. Im Output steht immer "MeinText"1
-
Moment, wenn ich eine globale Var endl vom Typ my_endl erzeuge gehts.
-
Es passt einfach net.
Alles was ich will ist, dass mein logfile auf ein endl anders reagiert
als mit die normalen Streams. Die normalen Streams sollen unverändert bleiben, Das kann doch net so schwer sein.
-
willst du das verhalten für std::endl ändern? Das kannst du nicht unabhängig von der verwendeten Std Lib machen. Du musst ein eigenes endl definieren, wie in meinem Code. Wo ist das Problem mit meinem Code?
-
Sry!
ICh war total übermühdet gestern.
Hab jetzt mein eigenes endl mit <<-Operatoren für logfile und std::ostream
und alles klappt.Das einzige Problem ist noch dass ich immer eine globale Variable von endl
brauche. Die Sache mit my_endl endl() funzt (noch) net. Aber vielleicht sieht
das nach weitern 2 Stunden Schlaf wieder anders ausThx
-
Mit kingruedis endl()-Funktion müsste es so gehen:
stream << my_endl();
Um die Klammern weglassen zu können, kannst du eine Funktion draus machen:
ostream& my_endl(ostream&) { ... }
Für solche Funktionen gibt es einen überladenen operator<<, der die Funktion auf dem Stream aufruft.
-
Wieso klappt der Trick mit der Funktion nur bei ostream und bei davon
abgeleiteten Klassen nicht?:xmas1:
-
Du meinst als Parameter und Rückgabewert? Weil es nur einen operator<< für diese Funktionssignatur gibt. Wenn du wirklich keinen eigenen streambuf schreiben willst (keine Ahnung, ob das in dein Konzept passt würde, aber ich kanns mir gut vorstellen), dann kannst du noch einen weiteren op<< schreiben:
ologstream& operator<<(ologstream& stream, ologstream& (*manip)(ologstream&)) { return manip(stream); } ologstream& endl(ologstream& stream) { return stream << "Hallo Manipulator!"; } ologstream str; str << "Hallo Log" << endl;
(Nicht getestet, aber so würd ich mir das vorstellen...)
-
Die Firma dankt