Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
719 connectés 

  FORUM HardWare.fr
  Programmation
  C++

  Type erasure et accesseurs

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

Type erasure et accesseurs

n°2019449
codablank
Posté le 27-08-2010 à 16:58:54  profilanswer
 

Bonjour, j'ai mis en place le "pattern" type erasure en C++, c-a-d que je masque une classe template avec une classe abstraite
 

Code :
  1. class Base{
  2.      virtual ~Base(){}
  3.      //méthodes virtuelles pures
  4. }
  5. template<typename T>
  6. class Derived : Base{
  7. Derived<T>(){}
  8. ~Derived(){}
  9. //méthodes publiques
  10. private :
  11. vector<T> datas;
  12. }


 
problème : si je veux faire récupérer ou modifier datas, je dois passer par Base
 
comment dois je définir les accesseurs getDatas() et SetDatas(vector<T> datas) ?

mood
Publicité
Posté le 27-08-2010 à 16:58:54  profilanswer
 

n°2019576
Taz
bisounours-codeur
Posté le 28-08-2010 à 12:35:00  profilanswer
 
n°2019578
Taz
bisounours-codeur
Posté le 28-08-2010 à 12:39:39  profilanswer
 

Cela dit leurs solution avec des type_info, c'est complètement délirant.
Ici t'as un problème qui se mort la queue. Tu fais une classe pour effacer le nature template des tes données, mais dedans tu inclus une collection template sans virtual.
 
La solution c'est que ta base ait une méthode virtual et que ces filles l'implémentes.
Et après si tu veux gérer une collection, et bien fais en sorte de gérer une collection de "Derived", c'est à dire que ton T soit effacé.
 
De toutes façons, le problème de la collection il est pas facile, parce que tu as un risque d'y mélanger des pommes et des oranges.

n°2019589
Taz
bisounours-codeur
Posté le 28-08-2010 à 13:46:13  profilanswer
 

Un exemple complet.
La solution c'est d'avoir un vector<Derived<T> > et pas vector<T>.
 

Code :
  1. #include <vector>
  2. #include <iostream>
  3. #include <algorithm>
  4. #include <iterator>
  5. class IObject
  6. {
  7. public:
  8.   virtual void assign(const IObject &other) = 0;
  9.   virtual void print(std::ostream & ) const = 0;
  10.   virtual ~IObject();
  11. };
  12. std::ostream & operator<<(std::ostream &out, const IObject &o)
  13. {
  14.   o.print(out);
  15.   return out;
  16. }
  17. IObject::~IObject()
  18. { }
  19. template <typename T>
  20. class Object
  21.   : public IObject
  22. {
  23. protected:
  24.   T data;
  25. public:
  26.   virtual void assign(const IObject &other)
  27.   {
  28.     this->data = dynamic_cast<const Object<T>&>(other).data;
  29.   }
  30. };
  31. template <typename T>
  32. class Vector
  33.   : public Object< std::vector<T> >
  34. {
  35. public:
  36.   template<typename Iterator>
  37.   void assign(Iterator begin, Iterator end)
  38.   {
  39.     this->data.clear();
  40.     std::copy(begin, end, std::back_inserter(this->data));
  41.   }
  42.   virtual void print(std::ostream &out) const
  43.   {
  44.     out << '(';
  45.     std::copy(this->data.begin(), this->data.end(), std::ostream_iterator<T>(out, ", " ));
  46.     out << ')';
  47.   }
  48. };
  49. #include <stdexcept>
  50. #include <iostream>
  51. int main()
  52. {
  53.   int integers[] = {1, 3, 5, 42 };
  54.   float floats[] = { 3.14, 0.0, 0.42};
  55.   Vector<int> vi1, vi2;
  56.   Vector<float> vf;
  57.   vi2.assign(integers, integers + 4);
  58.   vf.assign(floats, floats + 3);
  59.   IObject &a(vi1), &b(vi2), &c(vf);
  60.   std::cout << a << '\n'
  61.     << b << '\n'
  62.     << c << '\n';
  63.   try {
  64.     a.assign(b);
  65.     b.assign(c);
  66.   }
  67.   catch (std::exception &e) {
  68.     std::cerr << e.what() << '\n';
  69.   }
  70.   std::cout << a << '\n'
  71.     << b << '\n'
  72.     << c << '\n';
  73. }

n°2019596
Taz
bisounours-codeur
Posté le 28-08-2010 à 14:17:44  profilanswer
 

boost::any c'est également pas mal.

n°2020803
Glock 17Pr​o
Posté le 02-09-2010 à 17:39:15  profilanswer
 

Taz a écrit :

Un exemple complet.
La solution c'est d'avoir un vector<Derived<T> > et pas vector<T>.
 

Code :
  1. #include <vector>
  2. #include <iostream>
  3. #include <algorithm>
  4. #include <iterator>
  5. class IObject
  6. {
  7. public:
  8.   virtual void assign(const IObject &other) = 0;
  9.   virtual void print(std::ostream & ) const = 0;
  10.   virtual ~IObject();
  11. };
  12. std::ostream & operator<<(std::ostream &out, const IObject &o)
  13. {
  14.   o.print(out);
  15.   return out;
  16. }
  17. IObject::~IObject()
  18. { }
  19. template <typename T>
  20. class Object
  21.   : public IObject
  22. {
  23. protected:
  24.   T data;
  25. public:
  26.   virtual void assign(const IObject &other)
  27.   {
  28.     this->data = dynamic_cast<const Object<T>&>(other).data;
  29.   }
  30. };
  31. template <typename T>
  32. class Vector
  33.   : public Object< std::vector<T> >
  34. {
  35. public:
  36.   template<typename Iterator>
  37.   void assign(Iterator begin, Iterator end)
  38.   {
  39.     this->data.clear();
  40.     std::copy(begin, end, std::back_inserter(this->data));
  41.   }
  42.   virtual void print(std::ostream &out) const
  43.   {
  44.     out << '(';
  45.     std::copy(this->data.begin(), this->data.end(), std::ostream_iterator<T>(out, ", " ));
  46.     out << ')';
  47.   }
  48. };
  49. #include <stdexcept>
  50. #include <iostream>
  51. int main()
  52. {
  53.   int integers[] = {1, 3, 5, 42 };
  54.   float floats[] = { 3.14, 0.0, 0.42};
  55.   Vector<int> vi1, vi2;
  56.   Vector<float> vf;
  57.   vi2.assign(integers, integers + 4);
  58.   vf.assign(floats, floats + 3);
  59.   IObject &a(vi1), &b(vi2), &c(vf);
  60.   std::cout << a << '\n'
  61.     << b << '\n'
  62.     << c << '\n';
  63.   try {
  64.     a.assign(b);
  65.     b.assign(c);
  66.   }
  67.   catch (std::exception &e) {
  68.     std::cerr << e.what() << '\n';
  69.   }
  70.   std::cout << a << '\n'
  71.     << b << '\n'
  72.     << c << '\n';
  73. }



pourquoi t'utilise \n et pas endl


---------------
.
n°2020824
Un Program​meur
Posté le 02-09-2010 à 18:58:17  profilanswer
 

endl fait aussi un flush.


---------------
The truth is rarely pure and never simple (Oscar Wilde)
n°2020836
Glock 17Pr​o
Posté le 02-09-2010 à 19:28:34  profilanswer
 

dans quel cas sait-on qu'il est utile de faire un flush ou pas?

Message cité 1 fois
Message édité par Glock 17Pro le 02-09-2010 à 19:30:54

---------------
.
n°2020838
Glock 17Pr​o
Posté le 02-09-2010 à 19:33:27  profilanswer
 

IObject &a(vi1), &b(vi2), &c(vf); je comprends pas cette ligne non plus d'ailleurs


---------------
.
n°2020926
Un Program​meur
Posté le 03-09-2010 à 09:37:21  profilanswer
 

Glock 17Pro a écrit :

dans quel cas sait-on qu'il est utile de faire un flush ou pas?

 

Si tu peux attendre que le fichier soit ferme ou pas pour que les donnees soient envoyees a l'OS.

 
Glock 17Pro a écrit :

IObject &a(vi1), &b(vi2), &c(vf); je comprends pas cette ligne non plus d'ailleurs


Code :
  1. IObject& a(v1);
  2. IObject& b(v2);
  3. IObject& c(vf);


Message édité par Un Programmeur le 03-09-2010 à 09:37:30

---------------
The truth is rarely pure and never simple (Oscar Wilde)
mood
Publicité
Posté le 03-09-2010 à 09:37:21  profilanswer
 

n°2020959
Glock 17Pr​o
Posté le 03-09-2010 à 11:10:09  profilanswer
 

1.  le fichier sortie écran associé au programme est bien fermé au moment où le programme se termine, l'affichage se fera donc de manière certaine une fois que le programme sera terminer et non au moment de l'exec du prog ?
 
2. IObject& a(v1)
 
ok

Message cité 1 fois
Message édité par Glock 17Pro le 03-09-2010 à 11:20:51

---------------
.
n°2020974
Taz
bisounours-codeur
Posté le 03-09-2010 à 11:33:07  profilanswer
 

Les IObject& c'est des références, juste pour illustrer que le polymorphisme se met aussi en œuvre avec par les références.

n°2020988
Un Program​meur
Posté le 03-09-2010 à 11:55:00  profilanswer
 

Glock 17Pro a écrit :

1.  le fichier sortie écran associé au programme est bien fermé au moment où le programme se termine, l'affichage se fera donc de manière certaine une fois que le programme sera terminer et non au moment de l'exec du prog ?


Oui.  Mais tu veux pouvoir forcer certaines sorties avant la fin du programme.   Parce qu'on fait des entrees par exemple, mais pour ca il y a basic_ios::tie().


---------------
The truth is rarely pure and never simple (Oscar Wilde)
n°2021021
Glock 17Pr​o
Posté le 03-09-2010 à 13:41:32  profilanswer
 

Un Programmeur a écrit :


Oui.  Mais tu veux pouvoir forcer certaines sorties avant la fin du programme.   Parce qu'on fait des entrees par exemple, mais pour ca il y a basic_ios::tie().


quand tu dis pouvoir forcer tu penses à endl ou à basic_ios::tie() (que je ne connais pas d'ailleurs)


---------------
.
n°2021032
Taz
bisounours-codeur
Posté le 03-09-2010 à 14:43:44  profilanswer
 

D'abord, vous avez passé vos vies à utiliser printf avec des "\n" sans jamais vous poser de questions. Un jour votre prof de C++ vous dit que endl c'est mieux, c'est plus C++. Sauf que dans l'histoire, le seul moment où en C vous faites du fflush(stdout), c'est entre un printf("prompt:" ) et fgets. Manque de pot, cin/cout/cerr sont liés, ce qui fait que cout flush tout seul en cas de lecture sur cin.
 
Donc pratiquement, je n'ai jamais rencontré de cas où un endl se justifiait. J'utilise flush plus volontiers car plus explicite.

n°2021034
Glock 17Pr​o
Posté le 03-09-2010 à 14:48:35  profilanswer
 

c'est vraiment une abération d'avoir inventé ce endl alors!


---------------
.
n°2021040
Un Program​meur
Posté le 03-09-2010 à 14:58:06  profilanswer
 

Le C a une bufferisation par ligne qui n'existe pas en C++.  Celle-ci est remplacée par l'utilisation de endl.  On peut penser que l'usage n'est pas assez courant pour avoir mérité la normalisation de la fonction, mais de la a écrire que c'est aberrant, il y a un pas que je ne franchirai pas.  S'il y a une aberration, elle est plutôt a chercher du cote de la qualité de l'enseignement du C++.


---------------
The truth is rarely pure and never simple (Oscar Wilde)
n°2021048
Glock 17Pr​o
Posté le 03-09-2010 à 15:11:30  profilanswer
 

tout comme celle du java du c de tout en général si on va par là


---------------
.
n°2021054
Glock 17Pr​o
Posté le 03-09-2010 à 15:35:39  profilanswer
 

Un Programmeur a écrit :

Le C a une bufferisation par ligne qui n'existe pas en C++.  .


tu entends par là qu’après chaque '\n' un flush est effectué?


---------------
.
n°2021060
Un Program​meur
Posté le 03-09-2010 à 15:53:59  profilanswer
 

Oui.  Voir _IOLBF (oui cette constante est normalisee bien qu'elle commence par _ suivit d'une majuscule).


---------------
The truth is rarely pure and never simple (Oscar Wilde)
n°2021067
codablank
Posté le 03-09-2010 à 16:28:22  profilanswer
 

merci pour tes suggestions taz, entre temps j'ai trouvé une solution qui m'évite le cast, grâce à la méta-programmation et les templates
 
(un conteneur de conteneurs homogènes, en gros)
 
 :jap:

n°2021084
Glock 17Pr​o
Posté le 03-09-2010 à 17:15:29  profilanswer
 

tu peux poster ton code please


---------------
.
mood
Publicité
Posté le   profilanswer
 


Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  C++

  Type erasure et accesseurs

 

Sujets relatifs
Impossible de copier/coller un path dans un input type file sous FF3Erreur 13 :incompatibilité type
Macro: Changer le type du fichier dans Enregistrer sousConversion de type c pour une utilisation de dll VBA
Recherche editeur C type Nassi-Schneidermanget file content type
Problème type encodage ("é","è") etc..[C++] #include -> Type inconnu
Créer un widget type iframe pour afficher ses derniers articlesTraitement de gros fichiers TXT (type PHPMyAdmin)
Plus de sujets relatifs à : Type erasure et accesseurs


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR