Je voudrais contrôler ce qui est écrit dans un flux, c'est cout
-à- dire pour un objet d'une classe personnalisée. Est-ce possible en C ++? En Java, vous pouvez remplacer la toString()
méthode à des fins similaires.
Je voudrais contrôler ce qui est écrit dans un flux, c'est cout
-à- dire pour un objet d'une classe personnalisée. Est-ce possible en C ++? En Java, vous pouvez remplacer la toString()
méthode à des fins similaires.
Réponses:
En C ++, vous pouvez surcharger operator<<
pour ostream
et votre classe personnalisée:
class A {
public:
int i;
};
std::ostream& operator<<(std::ostream &strm, const A &a) {
return strm << "A(" << a.i << ")";
}
De cette façon, vous pouvez générer des instances de votre classe sur des flux:
A x = ...;
std::cout << x << std::endl;
Si vous operator<<
souhaitez imprimer les éléments internes de la classe A
et que vous avez vraiment besoin d'accéder à ses membres privés et protégés, vous pouvez également le déclarer comme une fonction d'ami:
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
, et aussi à l'intérieur du corps de la classe - avec cela, vous n'aurez pas à faire using namespace
pour l'espace de noms contenant l'opérateur (et la classe), mais ADL le trouvera tant que l'objet de cette classe est l'un des opérandes.
dump
méthode publique est sale et inutile. Utiliser friend
ici est parfaitement bien. Que vous préfériez une méthode redondante ou une méthode intrusive friend
est entièrement une question de goût, bien qu'elle friend
ait sans doute été introduite dans ce but précis.
operator<<()
une fonction membre ne fonctionnera pas: vous devrez en faire une fonction membre de std::ostream
pour qu'elle accepte un opérande de gauche de type std::ostream
.
Vous pouvez également le faire de cette façon, en permettant le polymorphisme:
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
comportement de Java .
En C ++ 11, to_string est finalement ajouté au standard.
http://en.cppreference.com/w/cpp/string/basic_string/to_string
ToString()
est une fonction virtuelle définie sur la classe de base de tous les objets, et est donc utilisée comme moyen standard pour exprimer une représentation sous forme de chaîne de n'importe quel objet. Ces fonctions std::string
ne s'appliquent qu'aux types intégrés. La manière idiomatique en C ++ est de remplacer l' <<
opérateur pour les types personnalisés.
operator<<
, par rapport à la String
sémantique simple de Java, m'incite à remarquer que ce to_string()
n'est pas seulement "un ajout utile", mais la nouvelle façon préférée de le faire en C ++. Si, comme par l'OP, une représentation sous forme de chaîne personnalisée d'une classe A
est souhaitée, il suffit d'écrire une string to_string(A a)
définition ci - dessous de class A
suffices. Cela se propage avec héritage comme en Java, et peut être combiné (par ajout de chaîne) comme en Java. Le non-overriden toString()
en Java est de toute façon d'un usage limité.
En tant qu'extension de ce que John a dit, si vous souhaitez extraire la représentation sous forme de chaîne et la stocker dans un, std::string
procédez comme suit:
#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
se trouve dans l'en- <sstream>
tête.
La question a reçu une réponse. Mais je voulais ajouter un exemple concret.
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;
}
Cet exemple nécessite de comprendre la surcharge de l'opérateur.