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 ostreamet 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 Aet 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 namespacepour 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.
dumpméthode publique est sale et inutile. Utiliser friendici est parfaitement bien. Que vous préfériez une méthode redondante ou une méthode intrusive friendest entièrement une question de goût, bien qu'elle friendait 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::ostreampour 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); }
toStringcomportement 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::stringne 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 Stringsé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 Aest souhaitée, il suffit d'écrire une string to_string(A a)définition ci - dessous de class Asuffices. 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::stringprocé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::stringstreamse 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.