overload <<, probleme :/

overload <<, probleme :/ - C++ - Programmation

Marsh Posté le 12-03-2004 à 15:30:22    

:hello: , dans le bouquin j ai ca :

Code :
  1. ostream& operator<<(ostream &out, const classname &var)


 
j ai une template de cette forme :

Code :
  1. #ifndef CIRCLET_H
  2. #define CIRCLET_H
  3. using namespace std;
  4. template <class T>
  5. class circle{
  6.   public:
  7.     circle();     
  8.     circle(const circle<T> & c);             
  9.     ect ect ...
  10.     ostream& operator <<(ostream &out, const  circle<T> &c);
  11.   private:
  12.    .......
  13. };
  14. template <class T>
  15. circle<T>::circle():length(0), ring(NULL) { }
  16. template <class T>
  17. ostream& operator<<(ostream &out, const  circle &c)
  18. {
  19. out << "test";
  20. //c.printCircle();
  21. return out;
  22. }


 
a la compilation j ai ce message d erreur :
 

Code :
  1. In file included from josept.cc:10:
  2. circlet.h:51: error: `std::ostream& circle<T>::operator<<(std::ostream&, const
  3.    circle<T>& )' must take exactly one argument
  4. circlet.h: In instantiation of `circle<std::string>':
  5. josept.cc:16:   instantiated from here
  6. circlet.h:51: error: `std::ostream& circle<T>::operator<<(std::ostream&, const
  7.    circle<T>& ) [with T = std::string]' must take exactly one argument
  8. zsh: exit 1     g++ -o josept.out josept.cc


 
il me parle du programme josept qui creer l objet, circle<string> c;
heu .. je comprend pas d ou viens le pb ?
merci,


Message édité par xiluoc le 12-03-2004 à 15:31:42
Reply

Marsh Posté le 12-03-2004 à 15:30:22   

Reply

Marsh Posté le 12-03-2004 à 15:35:48    

L'"operator <<" et l'"operator >>" ne peuvent pas être des fonctions membres de classe parceque le premier paramètre doit être un istream/ostream et qu'il ne t'est pas possible d'ajouter des fonctions membres dans ces classes ( pas proprement en tout cas :) )

Reply

Marsh Posté le 12-03-2004 à 21:43:44    

Comment je dois faire alors ?
c est la qu intervient les class friends non ?

Reply

Marsh Posté le 12-03-2004 à 21:48:28    

oui et non. si tu peux t'en passer cai mieux, cai en dernier recours
 
le problème des friends, c'est que c'est des passe-droit. et j'aime assez peu que des opérations comme la comparaison ou l'affichage soit planquées derrière un friend, comme si ces opérations publiques devaient reposer sur des données cachées : si je n'ai pas le droit de savoir ce qui est affiché et sur quoi est basé la comparaison, j'aime assez peu. mais c'est personnel comme point de vue

Reply

Marsh Posté le 12-03-2004 à 22:01:32    

qu elle solution me rest il alors ? vu que la sa marche pas .. :/

Reply

Marsh Posté le 12-03-2004 à 22:07:13    

faire un joli Iterator et voilà, puis faire une fonction externe qui affiche comme tu veux

Reply

Marsh Posté le 12-03-2004 à 22:12:32    

hum sa me complique la tache je n ai jamais fais d iterator, je vais essayer ..

Reply

Marsh Posté le 12-03-2004 à 22:15:13    

enfin, du moins, vois comment tu fais pour afficher un tableau : tu affiches chaque élément auxquels tu as acces. défini une façon d'avoir accès à tes éléments, et affiche les

Reply

Marsh Posté le 16-03-2004 à 11:53:16    

>défini une façon d'avoir accès à tes éléments, et affiche les
 
et paf tu petes l'encapsulation ,
d'ou le friend..

Reply

Marsh Posté le 17-03-2004 à 04:43:37    

meme en mettant friend devant ma fonction le message d erreur reste le meme :/

Reply

Marsh Posté le 17-03-2004 à 04:43:37   

Reply

Marsh Posté le 17-03-2004 à 09:11:08    

frenchkiss a écrit :

>défini une façon d'avoir accès à tes éléments, et affiche les
 
et paf tu petes l'encapsulation ,
d'ou le friend..


 
euh non  :heink:  
 

Code :
  1. template<class T>
  2. class MonConteneur
  3. {
  4.   public :
  5.   // pleisn de truc
  6.   T getValue( ) { return data; }
  7.   private :
  8. // plein de truc
  9. T data;
  10. };
  11. template<class T>
  12. ostream& operator<< ( ostream & os, const MonConteneur<T>& c )
  13. {
  14.    os << c. getValue();
  15.    return os;
  16. }


 
c'ets propre, respecte l'encapsulation et evite le friend.
Evidemment la classe est purement bateau.


Message édité par Joel F le 17-03-2004 à 09:12:02
Reply

Marsh Posté le 17-03-2004 à 10:35:31    

...
ouai ton getValue rentoure T
puis tu fais un os << T  
bravo!!!
tu m expliques ce que t as resolu la?
..a part rajouter une couche
 
 
>euh non
ben si , si ta logique c est de dire "je peux afficher que ce que je peux acceder" cf:
>comme si ces opérations publiques devaient reposer sur des >données cachées : si je n'ai pas le droit de savoir ce qui est >affiché et sur quoi est basé la comparaison, j'aime assez peu
 
 
alors ca veut dire que tu vas devoir mettre des accesseurs public pour tes donnees private, et ainsi permettre a n importe qui de visualiser ces donnees. si ca c 'est pas violer l encapsulation.
Je peux comprendre la reticence que vous avez a utiliser friend.
puisque c'est un mecanisme puissant qui si mal utilise permet de faire a peu pres n importe quoi.
c'est la raison pour laquelle il faut l'utiliser au bon moment. la surchage de l operatuer en fait parti a mon avis.
 
 
et si on prends un exemple:
voiture et garagiste
le garagiste pourrait tres bien etre un friend de la voiture sur certainnes de ces methodes getmotor() par exemple
l avantage c est aue le moteur n est accessible qu'au garagiste et que le conducteur par exmple n'aurai pas le droit d y toucher.
 
donc le friend dans ce cas permet au contraire de renforcer l'encapsulation en evitant de mettre un accesseur publique qui ne serve qu'au garagiste ( et je parle meme pas du replaceMotor par exemple)
 
fk
 

Reply

Marsh Posté le 17-03-2004 à 12:19:48    

en meme temp mon pb est toujours la, sa serait bien de donner des examples se basant sur ma template ;)

Reply

Marsh Posté le 17-03-2004 à 13:23:54    

frenchkiss a écrit :


alors ca veut dire que tu vas devoir mettre des accesseurs public pour tes donnees private, et ainsi permettre a n importe qui de visualiser ces donnees. si ca c 'est pas violer l encapsulation.


 
ben non.
 
@xiluoc :
tu peut te faire une methode print() publique de ton cercle qui prend en param un ostream
et surchargé ostream pour appeler print. je vois que ca pour eviter le friend.


Message édité par Joel F le 17-03-2004 à 13:30:27
Reply

Marsh Posté le 17-03-2004 à 13:35:01    

mais pour linstant c est aps trop grave d eviter le friend ou non tout ce qeu j eveus c est que ca marche, ensuite j essaieria sans le friend
 

Code :
  1. template <class T>
  2. friend ostream& operator<<(ostream &out, const  circle &c)
  3.   {
  4.      out << "test";
  5.      //c.printCircle();
  6.      return out;
  7.   }


 
retourn la meme erreur

Reply

Marsh Posté le 17-03-2004 à 13:35:05    

frenchkiss a écrit :


donc le friend dans ce cas permet au contraire de renforcer l'encapsulation


 
bon alors au temps pour moi :
http://www.gotw.ca/gotw/070.htm
 
bref, friend sur ostream ca passe. malheureusement pour lui ici, le friend template va avoir du mal à passer.

Reply

Marsh Posté le 17-03-2004 à 13:39:07    

xiluoc a écrit :

mais pour linstant c est aps trop grave d eviter le friend ou non tout ce qeu j eveus c est que ca marche, ensuite j essaieria sans le friend


Essaye :
 

Code :
  1. #ifndef CIRCLET_H
  2. #define CIRCLET_H
  3. using namespace std;
  4. template <class T>  
  5. class circle{
  6.  public:
  7.   circle();        
  8.   circle(const circle<T> & c);              
  9.   ect ect ...
  10.  
  11.   friend ostream& operator << <T> (ostream &out, const  circle<T> &c);
  12.  private:
  13.  .......
  14. };
  15. template <class T>
  16. circle<T>::circle():length(0), ring(NULL) { }
  17. template <class T>
  18. ostream& perator<<(ostream &out, const  circle<T> &c)
  19. {
  20.      out << "test";
  21.      //c.printCircle();
  22.      return out;
  23. }


 
Le modificateur friend ne marche que sur des classes ou fonctions.
OR ici tu l'affecte à une fonction template, un MODELE, il faut donc l'insatncier pour permettre de lui affecter le modificateur friend.
 
je suis pas super clair mais l'idée c'est ca.
 
tested & approved gcc 3.3
 
@frenchkiss : on pensait la même chose mais j'avais pas compris, mille excuses si je me susi emporté :jap:


Message édité par Joel F le 17-03-2004 à 13:42:23
Reply

Marsh Posté le 17-03-2004 à 13:46:32    

super merci !  

Reply

Marsh Posté le 17-03-2004 à 13:57:42    

ca marche ??

Reply

Marsh Posté le 17-03-2004 à 13:59:37    

heu je testerai demain en reboutant sous linux.
j y crois en tous cas =)

Reply

Marsh Posté le 17-03-2004 à 14:05:10    

^^ ok

Reply

Marsh Posté le 17-03-2004 à 14:40:10    

2 soluces  
 
no problemo joel ;)
 
   
  using namespace std;  
 
  class printable  
  {
   //private :)
  virtual ostream print(ostream& out) const = 0;
  public:
 friend ostream& operator << (ostream &out, const printable &c);  
  };
 
  ostream& operator << (ostream &out, const printable &c)
 {
   c.print(out);
   return out;
 }
 
   
  template <class T>  
 class circle : public printable {
      public:  
    circle (T e) ;      
      private:  
    ostream print(ostream& out) const{
     out<<bla;
    return out;
    }
    circle(const circle<T> & c) {};
    T bla;
   
     
  };  
   
   
  template <class T>  
   circle<T>::circle (T e): bla(e){ }  
 
 
    template <class T>  
 class square {
      public:  
    square (T e) ;      
   friend ostream& operator << (ostream &out, const square & sq);
      private:  
    ostream& print(ostream& out) const{
     out<<bla;
    return out;
    }
    square(const circle<T> & c) {};
    T bla;
   
     
  };  
   
   
  template <class T>  
   square<T>::square (T e): bla(e){ }  
 
  template <class T>  
ostream& operator << (ostream &out, const square<T> & sq)
{
 sq.print(out);
 return out;
}
 
   
 
int main(int argc, char* argv[])
{
 string st("gegege" );
  circle<string> moncircle( st );    
  cout << moncircle;
  square<string> monsqaure(st);
  cout<<endl<<monsqaure;
 return 0;
}
 

Reply

Marsh Posté le 18-03-2004 à 01:24:07    

sa marche =))

Reply

Marsh Posté le 18-03-2004 à 01:32:34    

ca compile bien  
 

Code :
  1. template <class T>
  2. ostream& operator<<(ostream &out, const  circle<T> &c)
  3. {
  4. //      out << "wewee";
  5. out <<  c.printCircle();
  6. return out;
  7. //      return out;
  8. }


 
mais quand je fais cout << c; (c etant mon obket circle)
y a desmessages d erreur
 
je dois passer les mauvasi paramtres, ce st as comem ca qu on utlise lo verload <<?

Reply

Marsh Posté le 18-03-2004 à 01:40:08    

return c.print(out);

Reply

Marsh Posté le 18-03-2004 à 01:41:59    

enfin bon tout ça c'est très crade, très crade. manque des virtual dans tous les sens, et puis quand on fait des template comme ça, ça sert à rien.
 
débarrase toi de la classe abstraite Java-isante, elle sert à rien

Reply

Marsh Posté le 18-03-2004 à 07:21:50    

Code :
  1. circle <string> c;
  2. c.insert("haha" );
  3. c.insert("hehe" );
  4. c.insert("hoho" );
  5. cout << c;


 
erreur
 

Code :
  1. circlet.h: In function `std::ostream& operator<<(std::ostream&, const
  2.    circle<T>& ) [with T = std::string]':
  3. josept.cc:22:   instantiated from here
  4. circlet.h:176: no matching function for call to `circle<std::string>::
  5.    printCircle(std::basic_ostream<char, std::char_traits<char> >& ) const'
  6. circlet.h:162: candidates are: void circle<T>::printCircle() [with T =
  7.    std::string]

Reply

Marsh Posté le 18-03-2004 à 07:29:42    

apperemtn sa viens d ema fonction print
 

Code :
  1. template <class T>
  2. void circle<T>::printCircle()
  3. {
  4. if (length==0) return;
  5. for (int i=0; i<length; i++)
  6. {
  7.  cout << ring->num << "\t";
  8.  ring=ring->next;
  9. }
  10. cout << endl;
  11. }

Reply

Marsh Posté le 18-03-2004 à 10:49:03    

regarde comment est defini la fonction print de la classe square
ci dessus.
 
pis ton message d erruer est qd meme assez explicite , ca tu devrait le trouver tout seul hein.
 
tu fais un cout  << c
avec  
[c++]
template <class T>  
  ostream& operator<<(ostream &out, const  circle<T> &c)  
  {  
    //      out << "wewee";  
    out <<  c.printCircle();  
    return out;  
    //      return out;  
  }  
[/c++]
 
ton print circle tu crois qu'il fait quoi???
 
essaie de bien comprendre ce qu'il se passe ; et lis les messages d erreur ;)
 
[taz] exact il manque un vitual sur le print de square ( si on considere que l 'on va la deriver..)
 
( square et circle sont 2 solutions distinctes dans mon post hein)
 
FK

Reply

Marsh Posté le 18-03-2004 à 10:49:30    

zut c pas ca les tag c++ , decidement :lol

Reply

Marsh Posté le 18-03-2004 à 10:53:20    

c [ cpp ] sans espace et [ /cpp ]

Reply

Marsh Posté le 18-03-2004 à 10:58:41    

Code :
  1. while (true)
  2. cout <<" merci Joel F"<<endl;


Message édité par frenchkiss le 18-03-2004 à 10:59:01
Reply

Marsh Posté le 18-03-2004 à 12:08:57    

hum

Code :
  1. ostream& print(ostream& out) const{
  2.     out<<bla;
  3.     return out;
  4.     }


 
 
 

Code :
  1. ostream& operator << (ostream &out, const square<T> & sq)
  2. {
  3. sq.print(out);
  4. return out;
  5. }


 
je dois donc faire
 

Code :
  1. template <class T>
  2. ostream& circle<T>::printCircle(ostream& circle_out)
  3. {
  4. if (length==0) return;
  5. for (int i=0; i<length; i++) 
  6. {
  7. circle_out << ring->num << "\t";
  8. ring=ring->next;
  9. }
  10. circle_out << endl;
  11. }


    [:dams86]  

Reply

Marsh Posté le 18-03-2004 à 12:12:25    

endl bordel :o

Reply

Marsh Posté le 19-03-2004 à 01:41:48    

heu... j y suis presque

Code :
  1. ostream& printCircle(ostream& out); 
  2. friend ostream& operator << <T> (ostream &out, const  circle<T>  &c);


 
 

Code :
  1. template <class T>
  2. ostream& circle<T>::printCircle (ostream& out)
  3. {
  4. if (length==0) out << " ";
  5. for (int i=0; i<length; i++)
  6. {
  7.  out << ring->num << "\t";
  8.  ring=ring->next;
  9. }
  10. }
  11. template <class T>
  12. ostream& operator<<(ostream &out, const  circle<T> &c)
  13. {
  14. return c.printCircle(out);
  15. }


 
ca al air bon pourtant.
 
masi j obtiens ca :
 

Code :
  1. circlet.h: In function `std::ostream& operator<<(std::ostream&, const
  2.    circle<T>& ) [with T = std::string]':
  3. josept.cc:22:   instantiated from here
  4. circlet.h:177: passing `const circle<std::string>' as `this' argument of `
  5.    std::ostream& circle<T>::printCircle(std::ostream& ) [with T = std::string]'
  6.    discards qualifiers


 
:/

Reply

Marsh Posté le 19-03-2004 à 07:49:54    

1) il sert à quoi le friend ?
2) il te manque des const

Reply

Marsh Posté le 20-03-2004 à 08:23:35    

le friend me sert accesder aux variables private.
 
j y arrive pas.
et je comprend pas le code example donne plus haut.
 

Code :
  1. using namespace std; 
  2.   class printable 
  3.   {
  4.    //private   
  5.   virtual ostream print(ostream& out) const = 0;
  6.  
  7.   //pourquoi const=0 ?
  8.   public:
  9.   friend ostream& operator << (ostream &out, const printable &c); 
  10.   };
  11.   //la on met pas template<class T> ? ni de circle<T>:: pour quoi ?
  12.   ostream& operator << (ostream &out, const printable &c)
  13. {
  14.    c.print(out);
  15.    return out;
  16. }
  17.  
  18.   template <class T> 
  19.   class circle : public printable {
  20.       public
  21.     circle (T e) ;     
  22.       private
  23.     ostream print(ostream& out) const{
  24.      out<<bla;
  25.     return out;
  26.     }
  27.     circle(const circle<T> & c) {};
  28.     T bla;
  29.  
  30.    
  31.   }; 
  32.  
  33.  
  34.   template <class T> 
  35.    circle<T>::circle (T e): bla(e){ }


 
et le reste encore moins.
 
Pour voir mon code en entier :
http://coulix-new.ozforces.com.au/circlet.h
http://coulix-new.ozforces.com.au/josept.cc
c est quand meme assez tordu la syntax tempalte :/


Message édité par xiluoc le 20-03-2004 à 08:24:33
Reply

Marsh Posté le 20-03-2004 à 08:39:56    

je t'ai donné la solution bourdel ... et t'as pas besoin de cette classe printable :x

Reply

Marsh Posté le 20-03-2004 à 08:46:25    

ben, tas solution marhce bien pour le <<
masi c est la fonction ostream& print circle que j arrive pas a  
faire marcher.

Reply

Marsh Posté le 20-03-2004 à 11:45:04    

tu n'en as pas B.E.S.O.I.N ...

Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed