Ich möchte steuern, was in einen Stream geschrieben wird, dh coutfür ein Objekt einer benutzerdefinierten Klasse. Ist das in C ++ möglich? In Java können Sie die toString()Methode für ähnliche Zwecke überschreiben .
Ich möchte steuern, was in einen Stream geschrieben wird, dh coutfür ein Objekt einer benutzerdefinierten Klasse. Ist das in C ++ möglich? In Java können Sie die toString()Methode für ähnliche Zwecke überschreiben .
Antworten:
In C ++ können Sie operator<<für ostreamund Ihre benutzerdefinierte Klasse überladen :
class A {
public:
int i;
};
std::ostream& operator<<(std::ostream &strm, const A &a) {
return strm << "A(" << a.i << ")";
}
Auf diese Weise können Sie Instanzen Ihrer Klasse in Streams ausgeben:
A x = ...;
std::cout << x << std::endl;
Wenn Sie operator<<Interna der Klasse ausdrucken Amöchten und wirklich Zugriff auf ihre privaten und geschützten Mitglieder benötigen, können Sie sie auch als Freundfunktion deklarieren:
class A {
private:
friend std::ostream& operator<<(std::ostream&, const A&);
int j;
};
std::ostream& operator<<(std::ostream &strm, const A &a) {
return strm << "A(" << a.j << ")";
}
friendund auch innerhalb des Hauptteils der Klasse - damit müssen Sie nicht using namespacefür den Namespace tun, der den Operator (und die Klasse) enthält, aber ADL wird es finden, solange das Objekt dieser Klasse ist einer der Operanden.
dumpöffentliche Methode ist schmutzig und unnötig. Die Verwendung friendhier ist vollkommen in Ordnung. Ob Sie eine redundante oder eine aufdringliche Methode bevorzugen, friendist völlig Geschmackssache, obwohl friendsie wohl genau für diesen Zweck eingeführt wurde.
operator<<()funktioniert das Erstellen einer Member-Funktion nicht: Sie müssten sie zu einer Member-Funktion machen, damit sie einen std::ostreamOperanden vom Typ für die linke Hand akzeptiert std::ostream.
Sie können dies auch auf diese Weise tun und Polymorphismus zulassen:
class Base {
public:
virtual std::ostream& dump(std::ostream& o) const {
return o << "Base: " << b << "; ";
}
private:
int b;
};
class Derived : public Base {
public:
virtual std::ostream& dump(std::ostream& o) const {
return o << "Derived: " << d << "; ";
}
private:
int d;
}
std::ostream& operator<<(std::ostream& o, const Base& b) { return b.dump(o); }
toStringVerhalten von Java zu kopieren .
In C ++ 11 wird to_string schließlich zum Standard hinzugefügt.
http://en.cppreference.com/w/cpp/string/basic_string/to_string
ToString()ist eine virtuelle Funktion für die Basisklasse aller Objekte definiert und wird daher als Standardmethode zum Ausdrücken einer Zeichenfolgendarstellung eines beliebigen Objekts verwendet. Diese Funktionen std::stringgelten nur für integrierte Typen. Die idiomatische Methode in C ++ besteht darin, den <<Operator für benutzerdefinierte Typen zu überschreiben .
operator<<im Vergleich zur einfachen StringSemantik von Java veranlasst mich zu der Bemerkung, dass dies to_string()nicht nur "eine nützliche Ergänzung" ist, sondern auch die neue bevorzugte Methode, dies in C ++ zu tun. Wenn wie beim OP eine benutzerdefinierte Zeichenfolgendarstellung einer Klasse Agewünscht wird, schreiben Sie einfach eine der string to_string(A a)folgenden Definitionen von class ASuffizienz. Dies wird mit Vererbung wie in Java weitergegeben und kann (durch Hinzufügen von Zeichenfolgen) wie in Java kombiniert werden. Das Nicht-Überschreiben toString()in Java ist ohnehin von begrenztem Nutzen.
Wenn Sie die Zeichenfolgendarstellung extrahieren und in einer folgenden std::stringDatei speichern möchten, gehen Sie wie folgt vor :
#include <sstream>
// ...
// Suppose a class A
A a;
std::stringstream sstream;
sstream << a;
std::string s = sstream.str(); // or you could use sstream >> s but that would skip out whitespace
std::stringstreambefindet sich in der <sstream>Kopfzeile.
Die Frage wurde beantwortet. Aber ich wollte ein konkretes Beispiel hinzufügen.
class Point{
public:
Point(int theX, int theY) :x(theX), y(theY)
{}
// Print the object
friend ostream& operator <<(ostream& outputStream, const Point& p);
private:
int x;
int y;
};
ostream& operator <<(ostream& outputStream, const Point& p){
int posX = p.x;
int posY = p.y;
outputStream << "x="<<posX<<","<<"y="<<posY;
return outputStream;
}
Dieses Beispiel erfordert das Verständnis der Bedienerüberlastung.