Wie auf Objekt schreiben -> LoggerObj << "Schreib das auf"; ?
-
Hallo,
Ich möchte einem Objekt (Logger) die Möglichkeit geben, Istreams zu "empfangen".
Es sollte schlussendlich möglich sein, auf das Objekt zu schreiben und diesen String in der Operator-Methode weiter zu verarbeiten.
Bsp:
Logger << "Meldung xy loggen";Ich habe verschiedenes schon über das Überschreiben der Stream-Operatoren gelesen. Aber etwas geht mir nicht auf:
Der Outstream-Operator
operator<<ist sicher nicht der richtige Operator, da ich ja nicht den Logger ausgeben, sondern im Logger etwas empfangen will.Der Istream-Operator operator>> scheint mir auch nicht der richtige zu sein. Schliesslich möchte ich
Obj << "String txt";und nicht"String txt" >> Objschreiben können.Mit welchem Operator erreiche ich den gewünschten Effekt?
-
op<< ist schon der richtige Operator. Denn dein Logger-Objekt empfängt zwar etwas, aber es dient logisch der Ausgabe. cout empfängt ja auch Daten, um sie dann auszugeben.
-
Oder um es ganz einfach zu merken:
Du schiebst etwas in den Logger rein alsooperator <<.Grüssli
-
Danke für eure Antworten.
Ich habe mich also gleich an die Implementation des <<operator gemacht.
Deklaration:
friend void operator << (Logger& log, const std::string& str) const;Implementation:
friend void Logger::operator <<(Logger& log, const string & str) const { this.log(str.c_str()); }Und die Fehlermeldung dazu:
Logger.h:46: error: non-member function 'void core::operator<<(core::Logger&, const std::string&)' cannot have cv-qualifierWas ist ein
cv-qualifier?
Die Deklaration ist doch richtig? Mit zwei ParameterLoggerundString. Schliesslich ist beilogger << "blah"der linke Operand ein Logger und der rechte Operand ein String.
-
cv-qualifier: const oder volatile.
Das Problem ist, dass operator << wohl kaum const sein wird.
-
Wie die Fehlermeldung bereits sagt, kann eine freie Funktion nicht const sein. Denn das const bezieht sich ja auf das umhüllende Objekt, das bei freien Funktionen nicht existiert.
Und this ist ein Zeiger.
-
lies dir ma noch mal durch, was genau friend macht und wie man den op<< überlädt - das, was du dort machst, sieht sehr stark danach aus, als ob du weder das eine noch das andere wüsstest ^^
bb
-
Michael E. schrieb:
Wie die Fehlermeldung bereits sagt, kann eine freie Funktion nicht const sein. Denn das const bezieht sich ja auf das umhüllende Objekt, das bei freien Funktionen nicht existiert.
Und this ist ein Zeiger.
Danke Michael E. & SeppJ, wusste nicht das
cv-qualifier == constgilt.
Danke unskilled, dein Post hat mir und wohl auch anderen Lesern nix gebracht.Habe das ganze nun zum Laufen gebracht:
Deklaration:
friend void operator<< (Logger& log, const std::string& str) ;Implementation:
void operator <<(Logger& log, const std::string & str) { log.log(str.c_str()); }Es sollte doch möglich sein diesen Operator auch als Member-Funktion (mit nur einem Parameter String) zu realisieren. Schliesslich ist der linke Operand keine fremde Klasse, sondern die Klasse Logger selbst. Oder liege ich da falsch
-
Was unskilled dir sagen wollte:
-
Das friend vor der Funktionsdefinition ist unsinnig. In deinem letzten Post ist es richtig, sofern die Deklaration in der Klasse Logger steht.
-
operator<< gibt den Stream zurück, in den geschrieben wurde, um Folgendes zu ermöglichen:
log << "Hallo" << "Welt"; // wird umgewandelt in: (operator<<(log, "Hallo")).operator<<(log, "Welt");Es sollte doch möglich sein diesen Operator auch als Member-Funktion (mit nur einem Parameter String) zu realisieren. Schliesslich ist der linke Operand keine fremde Klasse, sondern die Klasse Logger selbst. Oder liege ich da falsch
Welchen Vorteil hättest du davon, wenn op<< ein Member wäre? Du schließt damit nur die implizierte Konvertierung des ersten Parameters in ein Logger-Objekt aus.
-
-
du brauchst das friend auch jetzt noch nicht - oder ist log(const char*) (unsinnigerweise) nicht public?
ich nehm außerdem mal an, du arbeitest intern so und so mit nem ofstream, also:class Logger { std::ofstream stream; //... template <typename T> void log(const T &to_write) { stream << to_write; } }; template <typename T> Logger& operator<< (Logger &s, const T &in) { s.log(in); return s; }oder (allerdings find ich konstrukte wie logger.log(asd).log(sdf).log(dfg) hässlich, deshalb würd ichs nicht so machen)
class Logger { std::ofstream stream; //... template <typename T> Logger& log(const T &to_write) { stream << to_write; return *this; } }; template <typename T> Logger& operator<< (Logger &s, const T &in) { return s.log(in); }alternativ kannst du dir die log-fkt auch sparen - dann wirst du das friend brauchen - allerdings wär das nicht gerade sinnig...
bb