Entrees/sorties c++
Résolu/Fermé
Asterix2231
Messages postés
50
Date d'inscription
mardi 5 février 2008
Statut
Membre
Dernière intervention
16 avril 2013
-
14 janv. 2010 à 10:30
Asterix2231 Messages postés 50 Date d'inscription mardi 5 février 2008 Statut Membre Dernière intervention 16 avril 2013 - 15 janv. 2010 à 19:56
Asterix2231 Messages postés 50 Date d'inscription mardi 5 février 2008 Statut Membre Dernière intervention 16 avril 2013 - 15 janv. 2010 à 19:56
10 réponses
KX
Messages postés
16753
Date d'inscription
samedi 31 mai 2008
Statut
Modérateur
Dernière intervention
25 novembre 2024
3 019
14 janv. 2010 à 11:13
14 janv. 2010 à 11:13
J'ai repris ton code, et j'ai eu la même erreur. Voici le message complet :
Cette erreur se résout comme ceci : enlève le & dans ton paramètre de operator<<
Ça devrait mieux marcher, à moins qu'il y ait une erreur ailleurs ;-)
In function `std::ostream& operator<<(std::ostream&, Grain&)': no match for 'operator<<' in 'sortie << (+g)->Grain::getPos()' candidates are: (...) std::ostream& operator<<(std::ostream&, Vecteur&) std::ostream& operator<<(std::ostream&, Grain&)
Cette erreur se résout comme ceci : enlève le & dans ton paramètre de operator<<
std::ostream& operator<<(std::ostream& sortie, Vecteur v) std::ostream& operator<<(std::ostream& sortie, Grain g)
Ça devrait mieux marcher, à moins qu'il y ait une erreur ailleurs ;-)
Char Snipeur
Messages postés
9813
Date d'inscription
vendredi 23 avril 2004
Statut
Contributeur
Dernière intervention
3 octobre 2023
1 298
14 janv. 2010 à 12:48
14 janv. 2010 à 12:48
déjà, pos est privée, mais l'erreur ne concorde pas...
Le fait d'enlever les références n'est pas une bonne solution. J'essayerai d'abord en mettant const devant.
Le fait d'enlever les références n'est pas une bonne solution. J'essayerai d'abord en mettant const devant.
loupius
Messages postés
697
Date d'inscription
dimanche 1 novembre 2009
Statut
Membre
Dernière intervention
31 décembre 2017
148
14 janv. 2010 à 14:35
14 janv. 2010 à 14:35
Dans la classe 'Vecteur', la déclaration doit être:
friend ostream& operator<<(ostream& ostr, const Vecteur& v) { ostr << v.x << " " << v.y << " " << v.z; return (ostr); }Bonne continuation?
Char Snipeur
Messages postés
9813
Date d'inscription
vendredi 23 avril 2004
Statut
Contributeur
Dernière intervention
3 octobre 2023
1 298
14 janv. 2010 à 14:38
14 janv. 2010 à 14:38
je crois que ce n'est pas très ISO la déclaration de fonction dans une classe. Gcc 4 refuse en tout cas.
loupius
Messages postés
697
Date d'inscription
dimanche 1 novembre 2009
Statut
Membre
Dernière intervention
31 décembre 2017
148
>
Char Snipeur
Messages postés
9813
Date d'inscription
vendredi 23 avril 2004
Statut
Contributeur
Dernière intervention
3 octobre 2023
14 janv. 2010 à 14:47
14 janv. 2010 à 14:47
Je viens d'essayer avec un 4.4 et il ne dit rien. Mais peu importe, tu déclares le prototype dans la classe (il le faut bien pour que les fonctions aient accès aux membres privés de la classe) et tu explicites la fonction à l'extérieur.
Pour la question de l'ISO, je ne sais pas.
Pour la question de l'ISO, je ne sais pas.
Char Snipeur
Messages postés
9813
Date d'inscription
vendredi 23 avril 2004
Statut
Contributeur
Dernière intervention
3 octobre 2023
1 298
>
loupius
Messages postés
697
Date d'inscription
dimanche 1 novembre 2009
Statut
Membre
Dernière intervention
31 décembre 2017
14 janv. 2010 à 15:41
14 janv. 2010 à 15:41
non, bien sur, mais déclaration plus codage : là il y a un problème. Nous avons eu le souci, mais je ne sais plus exactement quand il se produisait.
Pour le friend, c'est pas la peine car x y z sont des membres public de Vecteur. Par contre pas pos de Grain
Pour le friend, c'est pas la peine car x y z sont des membres public de Vecteur. Par contre pas pos de Grain
KX
Messages postés
16753
Date d'inscription
samedi 31 mai 2008
Statut
Modérateur
Dernière intervention
25 novembre 2024
3 019
14 janv. 2010 à 14:45
14 janv. 2010 à 14:45
Je suis d'accord avec Char Snipeur, il faudrait mettre la déclaration éventuellement dans le fichier Vecteur.cpp mais en tout cas pas dans la définition de la classe.
Mais c'est vrai que comme rappelé par loupius, il manque friend dans la déclaration d'Asterix223, même si je ne comprends pas comment ça a pu marcher sans...
Mais c'est vrai que comme rappelé par loupius, il manque friend dans la déclaration d'Asterix223, même si je ne comprends pas comment ça a pu marcher sans...
Vous n’avez pas trouvé la réponse que vous recherchez ?
Posez votre question
Asterix2231
Messages postés
50
Date d'inscription
mardi 5 février 2008
Statut
Membre
Dernière intervention
16 avril 2013
11
14 janv. 2010 à 16:22
14 janv. 2010 à 16:22
Bonjour,
Merci pour vos réponses.
Comme je l'ai (mal?) expliqué dans mon post, ma fonction est déclarée friend dans ma classe Grain (fichier grain.h), et implémentée dans un autre fichier (grain.cpp). Elle devrait normalement avoir accès aux données privée de la classe Grain.
De plus comme l'a justement remarqué Char Snipeur, les données de la classe Vecteur sont toues publiques, donc accessibles.
Je viens d'essayer en ajoutant "const" (dans le .h et le .cpp):
ostream& operator<<(ostream& sortie, const Grain& G);
mais rien n'y fait, j'ai la même erreur.
D'autres idées? Ou j'abandonne l'idée de vouloir à tout pris faire deux fonctions et n'en utilise q'une du type:
friend ostream& operator<<(ostream& sortie, Grain G);
ostream& operator<<(ostream& sortie, Grain G){
return sortie << Grain._pos.x << Grain._pos.y << Grain._pos.z;
}
(ce qui compile, soit dit en passant)?
Merci pour vos réponses.
Comme je l'ai (mal?) expliqué dans mon post, ma fonction est déclarée friend dans ma classe Grain (fichier grain.h), et implémentée dans un autre fichier (grain.cpp). Elle devrait normalement avoir accès aux données privée de la classe Grain.
De plus comme l'a justement remarqué Char Snipeur, les données de la classe Vecteur sont toues publiques, donc accessibles.
Je viens d'essayer en ajoutant "const" (dans le .h et le .cpp):
ostream& operator<<(ostream& sortie, const Grain& G);
mais rien n'y fait, j'ai la même erreur.
D'autres idées? Ou j'abandonne l'idée de vouloir à tout pris faire deux fonctions et n'en utilise q'une du type:
friend ostream& operator<<(ostream& sortie, Grain G);
ostream& operator<<(ostream& sortie, Grain G){
return sortie << Grain._pos.x << Grain._pos.y << Grain._pos.z;
}
(ce qui compile, soit dit en passant)?
loupius
Messages postés
697
Date d'inscription
dimanche 1 novembre 2009
Statut
Membre
Dernière intervention
31 décembre 2017
148
14 janv. 2010 à 17:05
14 janv. 2010 à 17:05
Je ne sais pas si mon exemple répond à ta demande, car j'ai bien du mal à comprendre ce que tu veux vraiment. Pardonne-moi si je n'ai pas su interpréter tes explications.
Bonne continuation.
#include <iostream> #include <cstdlib> using namespace std; class Vecteur { public: Vecteur (int x0, int y0, int z0) : x(x0), y(y0), z(z0) {} private: int x, y, z; friend ostream& operator<<(ostream& sortie, Vecteur& V); }; ostream& operator<<(ostream& sortie, Vecteur& V) { cout << "(" << V.x << ", " << V.y << ", " << V.z << ")"; return sortie; } class Grain { public: Grain(int x, int y, int z) { pos = new Vecteur(x, y, z); } ~Grain() { delete pos; } private: Vecteur* pos; friend ostream& operator<<(ostream& sortie, Grain& G); }; ostream& operator<<(ostream& sortie, Grain& G) { cout << "grain=" << *G.pos << endl; return sortie; } int main(int argc, char *argv[]) { Grain grain(1, 2, 3); cout << grain; return EXIT_SUCCESS; } [loupius@p3000]$ g++ -Wall essai.cpp [loupius@p3000]$ ./a.out grain=(1, 2, 3) [loupius@p3000]$Nota: Avec mon compilateur (gcc 4.4.2), la compilation s'effectue très bien avec les fonctions dans les classes.
Bonne continuation.
Asterix2231
Messages postés
50
Date d'inscription
mardi 5 février 2008
Statut
Membre
Dernière intervention
16 avril 2013
11
14 janv. 2010 à 23:24
14 janv. 2010 à 23:24
Merci d'avoir passé un peu de temps sur mon problème.
Ce que je veux c'est surcharger l'opérateur << pour pouvoir écrire "cout << V;" et "cout << G" (où V est un vecteur et G est un grain) dans mon main et que cela m'affiche les cordonnées soit du vecteur, soir du centre du grain.
Comme je défini la position du centre du grain par un vecteur, j'ai pensé que la surcharge:
ostream& operator<<(ostream& sortie, Grain G){
...
}
pourrait appeler
ostream& operator<<(ostream& ostr, Vecteur V){
...
}
Maintenant avec le code que tu me donnes je suis d'accord, ca tourne. Seulement puisque tu affiches les coordonnées avec cout dans l'implémentation des deux fonctions qui nous intéressent, je ne vois plus trop l'utilité de retourner un flux (return sortie;) qui, dans ma tête, n'a pas changé au cours de la fonction... Ca je ne sais pas si c'est super clair :p
En tout cas merci, ca m'ira bien pour le moment, je vais potasser ça tranquillement.
Au revoir.
Ce que je veux c'est surcharger l'opérateur << pour pouvoir écrire "cout << V;" et "cout << G" (où V est un vecteur et G est un grain) dans mon main et que cela m'affiche les cordonnées soit du vecteur, soir du centre du grain.
Comme je défini la position du centre du grain par un vecteur, j'ai pensé que la surcharge:
ostream& operator<<(ostream& sortie, Grain G){
...
}
pourrait appeler
ostream& operator<<(ostream& ostr, Vecteur V){
...
}
Maintenant avec le code que tu me donnes je suis d'accord, ca tourne. Seulement puisque tu affiches les coordonnées avec cout dans l'implémentation des deux fonctions qui nous intéressent, je ne vois plus trop l'utilité de retourner un flux (return sortie;) qui, dans ma tête, n'a pas changé au cours de la fonction... Ca je ne sais pas si c'est super clair :p
En tout cas merci, ca m'ira bien pour le moment, je vais potasser ça tranquillement.
Au revoir.
loupius
Messages postés
697
Date d'inscription
dimanche 1 novembre 2009
Statut
Membre
Dernière intervention
31 décembre 2017
148
14 janv. 2010 à 23:51
14 janv. 2010 à 23:51
La surchage d'un opérateur d'une classe impose de retourner le type de la classe, il n'y a pas à discuter.
Mais en plus cela permet d'enchaîner les opérations.
Bonne continuation.
Mais en plus cela permet d'enchaîner les opérations.
Bonne continuation.
Char Snipeur
Messages postés
9813
Date d'inscription
vendredi 23 avril 2004
Statut
Contributeur
Dernière intervention
3 octobre 2023
1 298
15 janv. 2010 à 09:44
15 janv. 2010 à 09:44
La surchage d'un opérateur d'une classe impose de retourner le type de la classe, il n'y a pas à discuter.
je ne suis pas sur de comprendre...
Moi, j'aurai plutôt écris, mais je me trompe peut être :
je ne suis pas sur de comprendre...
Moi, j'aurai plutôt écris, mais je me trompe peut être :
ostream& operator<<(ostream& sortie, Grain& G) { sortie << "grain=" << *G.pos << endl; return sortie; }de cette façon on peut aussi écrire dans un fichier par exemple, non ?
loupius
Messages postés
697
Date d'inscription
dimanche 1 novembre 2009
Statut
Membre
Dernière intervention
31 décembre 2017
148
15 janv. 2010 à 14:10
15 janv. 2010 à 14:10
Oui bien sûr, il faut mettre 'sortie << ...' (Voir post n° 4). J'ai fait une erreur en recopiant un essai.
C'est sans doute cette erreur qui a fait dire à Astérix :'je ne vois plus trop l'utilité de retourner un flux'; il a raison de se poser la question mais la réponse est que de toutes façons on ne peut pas y couper: il faut retourner le type de la classe dont on a surchargé l'opérateur.
Bonne journée.
C'est sans doute cette erreur qui a fait dire à Astérix :'je ne vois plus trop l'utilité de retourner un flux'; il a raison de se poser la question mais la réponse est que de toutes façons on ne peut pas y couper: il faut retourner le type de la classe dont on a surchargé l'opérateur.
Bonne journée.
Char Snipeur
Messages postés
9813
Date d'inscription
vendredi 23 avril 2004
Statut
Contributeur
Dernière intervention
3 octobre 2023
1 298
15 janv. 2010 à 14:29
15 janv. 2010 à 14:29
il faut retourner le type de la classe dont on a surchargé l'opérateur
Soit je ne comprends pas ce que tu veux dire, soit j'ai des lacune.
par exemple, toi tu écrirais :
A A::operator double(){}
Soit je ne comprends pas ce que tu veux dire, soit j'ai des lacune.
par exemple, toi tu écrirais :
A A::operator double(){}
loupius
Messages postés
697
Date d'inscription
dimanche 1 novembre 2009
Statut
Membre
Dernière intervention
31 décembre 2017
148
>
Char Snipeur
Messages postés
9813
Date d'inscription
vendredi 23 avril 2004
Statut
Contributeur
Dernière intervention
3 octobre 2023
15 janv. 2010 à 15:23
15 janv. 2010 à 15:23
Il n'est effectivement pas obligatoire de retourner le type de la classe.
Je restais bloqué sur les opérateurs classiques avec lesquels je n'arrive pas à trouver un exemple où il n'est pas retourné un type de la classe. Par contre, je surchage souvent l'opérateur '[]' pour contrôler les débordements et effectivement (et évidemment) on ne retourne pas le type de la classe.
Quant aux opérateurs de conversion, je n'en ai jamais utilisé.
Merci de m'avoir sorti de mon erreur.
Je restais bloqué sur les opérateurs classiques avec lesquels je n'arrive pas à trouver un exemple où il n'est pas retourné un type de la classe. Par contre, je surchage souvent l'opérateur '[]' pour contrôler les débordements et effectivement (et évidemment) on ne retourne pas le type de la classe.
Quant aux opérateurs de conversion, je n'en ai jamais utilisé.
Merci de m'avoir sorti de mon erreur.
Asterix2231
Messages postés
50
Date d'inscription
mardi 5 février 2008
Statut
Membre
Dernière intervention
16 avril 2013
11
15 janv. 2010 à 17:34
15 janv. 2010 à 17:34
Bonjour,
En effet c'est ce qui m'a fait me questionner sur l'utilité de retourner un flux. Cependant je suis d'accord que par définition la surcharge, au moins de l'opérateur <<, nécessite de retourner un type ostream& pour l'usage que je veux en faire.
Par contre viens d'écrire ces lignes de codes pour tester, et il se trouve que ca fonctionne parfaitement:
vecteur.h
class Vecteur{
public:
double x,y,z;
Vecteur(double x0=0,double y0=0,double z0=0);
friend ostream& operator<<(ostream& ostr, Vecteur& V);
};
vecteur.cc
Vecteur::Vecteur(double x0, double y0, double z0){
x=x0;
y=y0;
z=z0;
}
ostream& operator<<(ostream& ostr, Vecteur& V){
ostr << V.x << " " << V.y << " " << V.z;
return ostr;
}
grain.h
class Grain{
Vecteur pos;
public:
Grain(double x0, double y,double z0);
friend ostream& operator<<(ostream& ostr, Grain& G);
};
grain.cc
Grain::Grain(double x0, double y0, double z0){
pos.x = x0;
pos.y = y0;
pos.z = z0;
}
ostream& operator<<(ostream& ostr, Grain& G){
ostr << G.pos;
return ostr;
}
main.cc
int main(){
Grain G(1,2,3);
cout << G << endl;
}
Ce qui en réalité correspond à ce que je souhaite faire depuis le début. Je dois avoir d'autres erreurs cachées les classes grain et vecteur initiales, qui sont plus grosses que ce que j'ai posté au début, et qui génèrent tout le blabla de mon compilateur.
Je vais regarder tout ça. Merci de vous êre penchés là dessus!
Bonne soirée.
En effet c'est ce qui m'a fait me questionner sur l'utilité de retourner un flux. Cependant je suis d'accord que par définition la surcharge, au moins de l'opérateur <<, nécessite de retourner un type ostream& pour l'usage que je veux en faire.
Par contre viens d'écrire ces lignes de codes pour tester, et il se trouve que ca fonctionne parfaitement:
vecteur.h
class Vecteur{
public:
double x,y,z;
Vecteur(double x0=0,double y0=0,double z0=0);
friend ostream& operator<<(ostream& ostr, Vecteur& V);
};
vecteur.cc
Vecteur::Vecteur(double x0, double y0, double z0){
x=x0;
y=y0;
z=z0;
}
ostream& operator<<(ostream& ostr, Vecteur& V){
ostr << V.x << " " << V.y << " " << V.z;
return ostr;
}
grain.h
class Grain{
Vecteur pos;
public:
Grain(double x0, double y,double z0);
friend ostream& operator<<(ostream& ostr, Grain& G);
};
grain.cc
Grain::Grain(double x0, double y0, double z0){
pos.x = x0;
pos.y = y0;
pos.z = z0;
}
ostream& operator<<(ostream& ostr, Grain& G){
ostr << G.pos;
return ostr;
}
main.cc
int main(){
Grain G(1,2,3);
cout << G << endl;
}
Ce qui en réalité correspond à ce que je souhaite faire depuis le début. Je dois avoir d'autres erreurs cachées les classes grain et vecteur initiales, qui sont plus grosses que ce que j'ai posté au début, et qui génèrent tout le blabla de mon compilateur.
Je vais regarder tout ça. Merci de vous êre penchés là dessus!
Bonne soirée.
Asterix2231
Messages postés
50
Date d'inscription
mardi 5 février 2008
Statut
Membre
Dernière intervention
16 avril 2013
11
15 janv. 2010 à 19:56
15 janv. 2010 à 19:56
Ce qui change en réalité, c'est que j'ai déclaré le prototype:
ostream& opérator<< (ostream& ostr, Vecteur V);
comme friend dans la classe vecteur.h, et là ça fonctionne. Je ne comprends cependant pas pourquoi c'est nécessaire, étant donné que toutes les données de cette classe sont publiques.
Au revoir.
ostream& opérator<< (ostream& ostr, Vecteur V);
comme friend dans la classe vecteur.h, et là ça fonctionne. Je ne comprends cependant pas pourquoi c'est nécessaire, étant donné que toutes les données de cette classe sont publiques.
Au revoir.