0

Ich möchte eine Funktion aufrufen, wenn m_logger<<"hello"<<"world" aufgerufen wird. m_logger ist vom Typ ofstream.Wie überlade ich den Operator <<?

Also entscheide ich < zu überlasten < mit Unterschrift folgenden

friend ofstream& operator<<(ofstream &stream,char *str); 

jedoch der vc Compiler folgenden Fehler gibt:

error C2666: 'operator <<' : 6 overloads have similar conversions

Gibt es anyother Weg, dies zu erreichen, mein Ziel ist, alle abzulenken die Schreiboperation von ofstream Objekt zu anderer Funktion?

Erstellen eines Objekts meiner eigenen Calss funktioniert für mich, aber wie kann ich es wie normale ofstream-Objekt arbeiten, die alle systemdefinierten Typen in Strings oder char * typisiert. Ich weiß, ein Ansatz wäre, den Operator für jeden einzelnen Typ zu überlasten, aber gibt es einen saubereren Ansatz

+0

@Kazoom: Ich habe meine Antwort bearbeitet, um den generischen Weg zu zeigen, alles an das interne 'ofstream' zu übergeben (es benutzt Funktionsvorlagen). – Zifre

Antwort

2

Das Problem ist, dass ofstream auf diese Weise bereits überlastet ist.Wenn Sie mlogger einen neuen Typ hält ein ofstream machen, dann können Sie dies tun:

class mlogger_t { 
public: 
    ofstream stream; 
    ... 
} 

mlogger_t& operator<<(mlogger_t& stream, const string& str) { 
    stream.stream << str; 
    ... 
} 

//EDIT: here is how to make this work for other types too using templates: 
template<typename T> mlogger_t& operator<<(mlogger_t& stream, T val) { 
    stream.stream << val; 
} 

... 

mlogger_t mlogger; 

mlogger << "foo"; 

Außerdem sollen Sie auf jeden Fall verwenden, um einen const string& (wie ich in diesem Beispiel angegeben), anstatt ein C-String. Wenn Sie wirklich benötigen, um C-Stil zu sein, mindestens const char * verwenden.

+0

das funktionierte für mich, aber es gibt noch ein Problem. Ich brauche mlogger, um genau wie Ofstream-Objekt zu arbeiten. Diese Methode schlägt fehl, wenn ich andere Ganzzahlen oder andere Typen als char * schreibe. Beispiel: mlogger << 3; Würde ich jeden bekannten Typ überladen müssen? damit das funktioniert? – Kazoom

+0

Sie könnten in diesem Fall eine Vorlage verwenden. – Zifre

2

Sie könnten den Typ des m_logger-Objekts ändern.

5

"Überlast" ist nicht "überschreiben". Sie können eine Funktion oder einen Operator für Argumente verschiedener Typen überladen; Sie können eine vorhandene Funktion oder einen vorhandenen Operator nicht mit einer eigenen Implementierung überschreiben (abgesehen von den virtuellen Funktionen, die offensichtlich sehr unterschiedlich sind). Die einzigen Ausnahmen sind operator new und operator delete, wo es möglich ist, eingebaute zu überschreiben.

1

Was Sie tun sollten, ist eine Klasse zu erstellen und dann operator<< zu definieren. Eine Operatorüberladung muss mindestens einen benutzerdefinierten Typ enthalten. Ebenso können Sie keinen neuen operator+(int, int) schreiben.

2

Je nach, warum Sie wollen Betreiber zu überlasten < <, die richtige Lösung ist entweder

  • eine andere Art zu verwenden, als ein Nachkomme von Ostream als Zielstrom; In diesem Fall müssen Sie alle Operatoren < < selbst schreiben, aber Sie können Hilfe von Vorlagen erhalten, wenn Sie standardmäßig weiterleiten möchten.

So:

template <typename T> 
myStream& operator<<(myStream& s, T const& v) 
{ 
    s.getStream() << v; 
} 

und Sie werden sehen, dass Manipulatoren die Vorlage nicht überein, so werden Sie auch brauchen so etwas wie:

myStream& operator<<(myStream& fl, std::ostream& (*fn)(std::ostream&)) 
{ 
    s.getStream() << fn; 
} 
  • zu schreiben Ihr eigener streambuf, der I/O an einen std :: filebuf delegiert (das ist ein wenig zu kompliziert, um hier ein Beispiel zu geben, im Internet zu suchen - filter streambuf ist ein gutes Schlüsselwort dafür. Wenn ich mich richtig erinnere, hat boost eine Hilfsbibliothek für das, was nützlich sein kann. Beachten Sie, dass Sie in diesem Fall wahrscheinlich einen anderen Typ als einen Stream verwenden, der jedoch von ostream abstammt.