Class Template + Friend

Class Template + Friend - C++ - Programmation

Marsh Posté le 27-11-2009 à 09:41:22    

Bonjour,
 
Comme le dis toujours Taz : pas de "PUTAIN DE FRIEND ... :o"
JE me demandais si il y avais une solution plus elegante que cela :  
 

Code :
  1. template<class T>
  2. class FileManager
  3. {
  4.     private:
  5.         char* Folder;
  6.         char* SubFolder;
  7.     public:
  8.         FileManager()                         : Folder("Last Project" ), SubFolder(typeid(T).name()) {}
  9.         FileManager(const char* folder) : Folder(folder),           SubFolder(typeid(T).name()) {}
  10.         ~FileManager() {}
  11.         void SetFolder     (const char* folder) {strcpy(Folder,folder);   }
  12.         void SetSubFolder(const char* folder) {strcpy(SubFolder,folder);}
  13.         const char* GetFolder     () const {return Folder;     }
  14.         const char* GetSubFolder() const {return SubFolder;}
  15.         template <typename  TT, typename U>
  16.         friend bool SaveFile(const TT&, const U&, bool, bool);
  17.         bool LoadFile() {return false;}
  18. };
  19. template<typename T, typename TT>
  20. bool SaveFile(const T& Classe, const TT& Obj, bool composite, bool normalize)
  21. {
  22.     const char* Extension = (normalize) ? ".npts" : ".pts";
  23.     char* File;
  24.     strcat(File, Classe.GetFolder()); strcat(File, Classe.GetSubFolder());
  25.    /.../


 
Le but est d`enregistrer les membres de mes classes etants des vect, vect<vect>, vec<list, list<pair< .... dans des repertoir correspond au nom des classes de maniere generique.
 
JE vous remercie d`avance.


---------------
“L'éducation est l'arme la plus puissante que l'on puisse utiliser pour changer le monde”
Reply

Marsh Posté le 27-11-2009 à 09:41:22   

Reply

Marsh Posté le 27-11-2009 à 14:31:34    

Remarque générale: oublie les char*, utilise des std::string.
 
Sinon, vu l'usage que tu veux, qu'est-ce qui t'empêches de faire de SaveFile une fonction membre ?
 

Reply

Marsh Posté le 27-11-2009 à 18:49:11    

regle #0 : friend ne sert à rien, jamais ...

Reply

Marsh Posté le 27-11-2009 à 18:58:02    

Bande d'associaux !

Reply

Marsh Posté le 27-11-2009 à 21:45:40    

ne sert à rien , jamais, ça me semble un peu excessif de dire ça.
 
 
pour éclater une classe en deux , ça peut être pratique


Message édité par Glock 17Pro le 27-11-2009 à 21:52:20

---------------
.
Reply

Marsh Posté le 27-11-2009 à 22:09:56    

et pourquoi donc tu aurais besoin de friend ?
friend pete l'encapsulation et rend le code moins générique. C'ets un hack qui ne devrait mm pas faire partie du langage

Reply

Marsh Posté le 27-11-2009 à 23:03:59    

Défois une classe et uniquement une classe à besoin d'accéder aux donnés privées d'une autre classe. Avoir des get/set pour juste cette classe, ça me semble particulièrement péter l'encapsulation car ça dévoile la structure de la classe. un coup de friend et c'est réglé.
 
moralité avoir des amis c'est bien, C++ l'a compris. :D


---------------
.
Reply

Marsh Posté le 28-11-2009 à 08:36:25    

sauf que si tu en es arrivé à ce design, c'ets que ton modèle est foireux.
donne moi un exemple et on va voir :o

Reply

Marsh Posté le 28-11-2009 à 10:31:31    

une classe de tests unitaires?  

Reply

Marsh Posté le 28-11-2009 à 13:10:31    

Code :
  1. class X {
  2.  int i;
  3. public:
  4.  void m();
  5.  friend void f(X& );
  6.  // ...
  7. };


---------------
.
Reply

Marsh Posté le 28-11-2009 à 13:10:31   

Reply

Marsh Posté le 28-11-2009 à 13:12:06    

sinon bon exemple la classe de tests unitaires


---------------
.
Reply

Marsh Posté le 28-11-2009 à 13:16:20    

ou quand tu as une grosse classe que tu veux splitter en deux, pour par exemple des soucis de clarté du code, tu veux garder les deux classes intimement liées, tu veux quelles se partagent les mêmes membres, mais tu ne souhaites pas mettre des méthodes publics.


---------------
.
Reply

Marsh Posté le 28-11-2009 à 13:21:25    

GrosBocdel a écrit :

une classe de tests unitaires?  


 
Regarde Boost.Test et tu verras que non :o
Ton exemple n'est pas en un exemple vu que y a qu'une classe ...
alros file un VRAI exemple ;)

Reply

Marsh Posté le 28-11-2009 à 13:25:43    

Un des logiciels de TU du commerce fait comme ça pour instrumenter le code.
Sinon j'ai pas d'autre exemple non

Reply

Marsh Posté le 28-11-2009 à 15:22:26    

template<typename T>
class Foo {
   T value;
public:
   Foo(const T& t) { value = t; }
   friend ostream& operator<<(ostream& os, const Foo<T>& b)
   {
      return os << b.value;
   }
};


---------------
.
Reply

Marsh Posté le 28-11-2009 à 15:47:10    

faudrait arrêter de penser que friend c'est le mal...


---------------
.
Reply

Marsh Posté le 28-11-2009 à 17:11:08    

c'ets pas que c'est le mal, c'ets que ca sert à rien.
l'exempel de operator<< est aussi foireux.

Reply

Marsh Posté le 28-11-2009 à 19:04:20    

[]d'accord
[X]pas d'accord


---------------
.
Reply

Marsh Posté le 28-11-2009 à 20:04:54    

si. Affichez le contenu d'une classe en allant chercher des membres privés sans accesseur, c'ets comme regarder sous une jupe, ca ne se fait pas.

Reply

Marsh Posté le 28-11-2009 à 20:21:31    

je trouve l'entorse à cette règle justifiée et la solution élégante


Message édité par Glock 17Pro le 28-11-2009 à 20:34:18

---------------
.
Reply

Marsh Posté le 28-11-2009 à 20:37:23    

bof non. Une methode display() accéder depuis un op<< non riend l'ai tout autant.

Reply

Marsh Posté le 28-11-2009 à 20:41:52    

un autre exemple :
 

Code :
  1. class Base1 
  2. {
  3.   public:
  4.       virtual int open (int) = 0;
  5.       /* virtual */ ~Base1() {} 
  6. };
  7. class Base2
  8. {
  9.   public:
  10.       virtual int open (int) = 0;
  11.       /* virtual */ ~Base2() {} 
  12. };
  13. class Derived 
  14. {
  15.   class Base1_Impl;
  16.   friend class Base1_Impl;
  17.   class Base1_Impl: public Base1 
  18.   {
  19.      public:
  20.        Base1_Impl (Derived * p) : parent_ (p) {}
  21.        virtual int open (int)
  22.        {
  23.           return parent_->base1_open ();
  24.        }
  25.      private:
  26.        Derived * parent_;
  27.   } base1_obj;   
  28.   class Base2_Impl;
  29.   friend class Base2_Impl;
  30.   class Base2_Impl: public Base2 
  31.   {
  32.      public:
  33.        Base2_Impl (Derived * p) : parent_ (p) {}
  34.        virtual int open (int)
  35.        {
  36.           return parent_->base2_open ();
  37.        }
  38.      private:
  39.        Derived * parent_;
  40.   } base2_obj;
  41.   int base1_open () {}
  42.   int base2_open () {}
  43.   public:
  44.     Derived () : base1_obj (this), base2_obj(this) {}
  45.     operator Base1 & () { return base1_obj; }
  46.     operator Base2 & () { return base2_obj; }
  47. };
  48. int base1_open (Base1 & b1)
  49. {
  50.   return b1.open (1);
  51. }
  52. int base2_open (Base2 & b2)
  53. {
  54.   return b2.open (2);
  55. }
  56. int main (void)
  57. {
  58.   Derived d;
  59.   base1_open (d); 
  60.   base2_open (d); 
  61. }


Message édité par Glock 17Pro le 28-11-2009 à 20:53:11

---------------
.
Reply

Marsh Posté le 28-11-2009 à 20:52:34    

et protected tu sais ce que ca veut dire ou bien o_O ?
c'ets quoi le use case de cette horreur ? genre les namespace anonymes c'est pr les bmanouches ?


Message édité par Joel F le 28-11-2009 à 20:58:14
Reply

Marsh Posté le 28-11-2009 à 20:56:34    

ça briserais  l'encapsulation


---------------
.
Reply

Marsh Posté le 28-11-2009 à 20:58:30    

Glock 17Pro a écrit :

ça briserais  l'encapsulation


mais jamais de la vie !
ton truc tu sasi hein, c'ets juste ça :

 
Code :
  1. class Derived : public Base1, public Base2
  2. {
  3.   public:
  4.   Derived ()  {}
  5.   virtual int open (int) {}
  6. };

...


Message édité par Joel F le 28-11-2009 à 21:00:23
Reply

Marsh Posté le 28-11-2009 à 21:02:46    

ET OUI mais quelle méthode  open appeler celle de Base1 ou de Base2...


---------------
.
Reply

Marsh Posté le 28-11-2009 à 21:06:25    

t'as qu'à avoir des interfaces propres déjà :o
Ce use-case, comme je te l'ai dis, est moisi des sa conception. Tu hérites de deux interfaces avec les memes méthodes publiques. tu t'attends à quoi ?
 
utiliser un truc uniquement pour faciliter des use case eux même foireux, ca ne vaut rien.

Reply

Marsh Posté le 28-11-2009 à 21:12:49    

bah imagine une classe Action, une classe Obligation toutes les deux ont une méthode price public. maintenant imagine une classe obligation convertible avec des propriétés à la fois Action et Obligation....


---------------
.
Reply

Marsh Posté le 28-11-2009 à 21:20:07    

J'imagine surtout que tu violes pas mal de principe objet.
ObligationConvertible IS_NOT_A une Action et une Obligation et donc, pas d'héritage possible.
 
Action et Obligation devrait implanter l'interface "Pricable" et OC aussi, mais sans hériter de Action et de Obligation.

Reply

Marsh Posté le 28-11-2009 à 21:24:13    

bon bon ok l'exemple était pas bon


---------------
.
Reply

Marsh Posté le 28-11-2009 à 21:28:06    

ca fait que le 3e :o
tu verras que tout exemple justifiant les friend se reecrit sans friend de manière triviale

Reply

Marsh Posté le 28-11-2009 à 21:31:04    

ui mais avec l'exemple de l'operator <<, ta solution est plus verbeuse


---------------
.
Reply

Marsh Posté le 28-11-2009 à 21:38:38    

et ? t'es payé à la ligne de code non écrite toi ?

Reply

Marsh Posté le 28-11-2009 à 21:43:02    

non mais les collègues gueule quand y a trop de ligne à lire pour faire une action, alors que celle ci pourrait être écrite en prenant moins de lignes sans être moins lisible


---------------
.
Reply

Marsh Posté le 28-11-2009 à 21:52:13    

après si ils aiment écrire du code moche, je m'en moque. C'est leur problème. Ils croient quoi ? que ca va aller moins vite :o

Reply

Marsh Posté le 28-11-2009 à 22:51:15    

moche moche hum


---------------
.
Reply

Marsh Posté le 30-11-2009 à 12:25:37    

Taz a écrit :

Remarque générale: oublie les char*, utilise des std::string.
 
Sinon, vu l'usage que tu veux, qu'est-ce qui t'empêches de faire de SaveFile une fonction membre ?
 


 
-------- Il y a des jours ou faut pas se lever.  :hello:


Message édité par kirua_sama le 30-11-2009 à 12:35:52

---------------
“L'éducation est l'arme la plus puissante que l'on puisse utiliser pour changer le monde”
Reply

Marsh Posté le 30-11-2009 à 12:35:55    

une methode save() et une fonction save qui appelle la dite methode.

Reply

Marsh Posté le 30-11-2009 à 14:38:06    

Joel F a écrit :

une methode save() et une fonction save qui appelle la dite methode.


 
D`accord, mais lorsque je vais ajouter une function load, verification de l`integrite des donnees etc etc...  
La semantique du soft sera immonde en procedant de cette maniere.


---------------
“L'éducation est l'arme la plus puissante que l'on puisse utiliser pour changer le monde”
Reply

Marsh Posté le 30-11-2009 à 14:59:01    

Joel F a écrit :

si. Affichez le contenu d'une classe en allant chercher des membres privés sans accesseur, c'ets comme regarder sous une jupe, ca ne se fait pas.


Ben sauf dans le cas d'une lib de sérialisation cf boost::serialization

Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

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