Ich möchte steuern, was in einen Stream geschrieben wird, dh cout
fü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 cout
fü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 ostream
und 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 A
mö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 << ")";
}
friend
und auch innerhalb des Hauptteils der Klasse - damit müssen Sie nicht using namespace
fü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 friend
hier ist vollkommen in Ordnung. Ob Sie eine redundante oder eine aufdringliche Methode bevorzugen, friend
ist völlig Geschmackssache, obwohl friend
sie 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::ostream
Operanden 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); }
toString
Verhalten 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::string
gelten 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 String
Semantik 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 A
gewünscht wird, schreiben Sie einfach eine der string to_string(A a)
folgenden Definitionen von class A
Suffizienz. 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::string
Datei 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::stringstream
befindet 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.