Plusieurs types dans un vector

Plusieurs types dans un vector - C++ - Programmation

Marsh Posté le 18-03-2004 à 09:53:00    

Je voudrai simplement mettre des types différents dans un même vector, voici un exemple des types :

Code :
  1. map<string, T>
  2. map<float, T>
  3. map<int, T>


 
Quelqu'un a une solution ?

Reply

Marsh Posté le 18-03-2004 à 09:53:00   

Reply

Marsh Posté le 18-03-2004 à 09:57:47    

Il va falloir utiliser le polymorphisme.
Fait heriter les types qui vont etre stockées dans ton vector d'une même classe mêre. Ensuite stocke dans ton vecteur des Pointeurs vers cette classe mêre.
 

Code :
  1. struct Value
  2. {
  3.     virtual void whoami()=0;
  4. };
  5. class CharValue : public Value
  6. { public : virtual void whoami() {cout << "char";} };
  7. class LongValue : public Value
  8. {public : virtual void whoami() {cout << "long";} };
  9. class FloatValue : public Value
  10. {public : virtual void whoami() {cout << "float";} };
  11. typedef vector<Value*> ValueVector;
  12. int main( int,char**)
  13. {
  14.     CharValue cv;
  15.     LongValue cl;
  16.     FloatValue cf;
  17.     ValueVector v;
  18.     v.push_back(&cv);
  19.     v.push_back(&cl);
  20.     v.push_back(&cf);
  21.     // Acces au elements
  22.     Value* it = v.begin();
  23.     while( it != v.end() )
  24.     {
  25.         *it->whoami();
  26.           it++;
  27.     }
  28.     return 0;
  29. }


Message édité par Joel F le 18-03-2004 à 09:59:14
Reply

Marsh Posté le 18-03-2004 à 10:08:17    

Merci bien, bon voila ce que j'ai fait (oulha c'est pas beau). (je précise que ce n'est qu'un code de test et pas un code final)
 

Code :
  1. /**
  2.   * Fichier principal de test des tables en mémoire
  3.   */
  4. //désactive le warning 4786 (bug de krosoft avec les 'map' pour changer un peu)
  5. #pragma warning(disable : 4786)
  6. #include <iostream>
  7. #include <vector>
  8. #include <map>
  9. #include <list>
  10. #include <string>
  11. using namespace std;
  12. #include "baseType.h"
  13. //les définitons de type  
  14. typedef vector<BaseType*> Record;
  15. typedef list<Record > Table;
  16. typedef map<BaseType, Record> Index;
  17. class BaseIndex
  18. {
  19. public:
  20.    void operator[](const BaseType* bt){};
  21. };
  22. class CharIndex : public BaseIndex
  23. {
  24. public:
  25.    Record& operator[](const BaseType* bt)
  26.    {
  27.       return this->index[*((Char*)bt)];
  28.    }
  29. private :
  30.    map<Char, Record> index;
  31. };
  32. class IntIndex : public BaseIndex
  33. {
  34. public:
  35.    Record& operator[](const BaseType* bt)
  36.    {
  37.       return this->index[*((Int*)bt)];
  38.    }
  39. private :
  40.    map<Int, Record> index;
  41. };
  42. typedef vector<BaseIndex*> Indexes;
  43. int main(int argc, char** argv)
  44. {
  45.    //exemple d'utilisation d'index
  46.    //la table
  47.    Table table;
  48.    //création de trois enregistrements
  49.    Record e1(2), e2(2), e3(2);
  50.    e1[0] = new Char('a');
  51.    e1[1] = new Int(1);
  52.    e2[0] = new Char('b');
  53.    e2[1] = new Int(2);
  54.    e3[0] = new Char('c');
  55.    e3[1] = new Int(3);
  56.    //on insère les trois enregistrements (lignes)
  57.    table.push_back(e1);
  58.    table.push_back(e2);
  59.    table.push_back(e3);
  60.    //création d'un index sur le premier et deuxième champs
  61.    CharIndex index0;
  62.    IntIndex index1;
  63.  
  64.    //on insère successivement les enregistrements dans l'index
  65.    for(Table::iterator i = table.begin(); i != table.end(); i++)
  66.    {
  67.       index0[(*i)[0]] = *i;
  68.       index1[(*i)[1]] = *i;
  69.    }
  70.  
  71.    //affichage de la ligne dont le champs 0 est 'b'
  72.    Char* search0 = new Char('b');
  73.    Record r0 = index0[search0];
  74.    delete search0;
  75.    cout << r0[0]->getChar() << "|" << r0[1]->getInt() << endl;
  76.    //affichage de la ligne dont le champs 1 est '3'
  77.    Int* search1 = new Int(3);
  78.    Record r1 = index1[search1];
  79.    delete search1;
  80.    cout << r1[0]->getChar() << "|" << r1[1]->getInt() << endl;
  81.    return 0;
  82. }

Reply

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

faut declarer tes operator[] virtuelle sino tu n'arrivera à rien.

Reply

Marsh Posté le 18-03-2004 à 10:35:25    

Des cast a la C ! C'est crade tout ça.

Reply

Marsh Posté le 18-03-2004 à 10:38:47    

Kristoph a écrit :

Des cast a la C ! C'est crade tout ça.


 
chut faut pas lui dire  :whistle:

Reply

Marsh Posté le 18-03-2004 à 10:42:51    

Joel F a écrit :


 
chut faut pas lui dire  :whistle:  


 
Mais si on le fait pas, ça va être la boucherie quand Taz va arriver sur ce topic
 
[:totoz]


Message édité par Kristoph le 18-03-2004 à 10:43:01
Reply

Marsh Posté le 18-03-2004 à 10:44:11    

deja que ^^.
 
Bon : Ummon,
 
dynamic_cast et static_cast sont tes amis

Reply

Marsh Posté le 18-03-2004 à 10:56:47    

zavez pas l impression qu'il manque un template qq part la  
 
FK

Reply

Marsh Posté le 18-03-2004 à 11:00:20    

pas template !, après on ne plus faire ca : vector<BaseIndex*> :)

Reply

Marsh Posté le 18-03-2004 à 11:00:20   

Reply

Marsh Posté le 18-03-2004 à 11:01:29    

Joel F a écrit :

deja que ^^.
 
Bon : Ummon,
 
dynamic_cast et static_cast sont tes amis


 
Oui mais même, je pense que ça modelisation est à revoir en fait. Les cast c'est mal et les cast à la C c'est très mal :)
 
Dans ce cas précis, le typage est faible et tu utilises un cast. Donc, cela suppose que d'une manière ou d'une autre, tu sais quel est le type de données stocké dans ton vecteur non ? un moyen d'eviter le cast est donc de donner au compilateur cette information.
 

Code :
  1. typedef vector<BaseType*> Record;
  2. Record e1(2);
  3. e1[0] = new Char('a');
  4. e1[1] = new Int(1);


 
Deviens alors :

Code :
  1. struct Record
  2. {
  3.   Char champ1;
  4.   Int champ2;
  5. };
  6. Record e1;
  7. e1.champ1 = new Char('a');
  8. e1.champ2 = new Int(1);


 
Enfin, vous voyez l'idée.


Message édité par Kristoph le 18-03-2004 à 11:07:46
Reply

Marsh Posté le 18-03-2004 à 11:05:39    

Joel F a écrit :

faut declarer tes operator[] virtuelle sino tu n'arrivera à rien.


oui c'était un oubli, c'est corrigé

Reply

Marsh Posté le 18-03-2004 à 11:07:05    

Kristoph a écrit :


 
Mais si on le fait pas, ça va être la boucherie quand Taz va arriver sur ce topic
 
[:totoz]

M'etonne qu'on l'ait pas encore vu d'ailleurs.
A+,


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 18-03-2004 à 11:09:54    

>Kristoph  
ok, mais les records vont dans des tables, dans mon cas je n'ai qu'un seul type de table pour n'importe quel type d'enregistrement (record) alors qu'avec ta facon de faire il faudrait faire un type pour chaque table. Mais je suis d'accord qu'a un moment ou à un autre je dois savoir quelle est la structure d'une table.


Message édité par Ummon le 18-03-2004 à 11:10:43
Reply

Marsh Posté le 18-03-2004 à 11:13:15    

Ummon a écrit :

pas template !, après on ne plus faire ca : vector<BaseIndex*> :)


 
bah pas si tu fais un template qui derive de cette classe...
 

Code :
  1. template <class T>
  2. class Type : public TypeBase{
  3. .....
  4. etc...
  5. et ensuite
  6.  
  7. Record e1(2), e2(2), e3(2);
  8.       e1[0] = new Type<char>('a');
  9.        e1[1] = new Type<int>(1);
  10.        e2[0] = new Type<char>('b');
  11.        e2[1] = new Type<int>(2);
  12.        e3[0] = new Type<char>('c');
  13.        e3[1] = new Type<int>(3);


Message édité par frenchkiss le 18-03-2004 à 11:14:03
Reply

Marsh Posté le 18-03-2004 à 11:15:36    

marche pas "Type<char>" et "Type<int>" sont des types différents

Reply

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

bien sur que ca marche..

Reply

Marsh Posté le 18-03-2004 à 11:16:23    

le template est une sorte de preprocessing

Reply

Marsh Posté le 18-03-2004 à 11:16:39    

bon alors je teste pour être sur

Reply

Marsh Posté le 18-03-2004 à 11:23:08    

Ummon a écrit :

le template est une sorte de preprocessing


 
P.A.S.D.U.T.O.U.T

Reply

Marsh Posté le 18-03-2004 à 11:30:29    

>Joel F
T'as une explication ou un lien concernant les models stp ?

Reply

Marsh Posté le 18-03-2004 à 11:35:36    

Reply

Marsh Posté le 18-03-2004 à 11:40:48    

>frenchkiss
bon ok, ca fonctionne, j'ai rien mais voila, comment résoudre ce problème :

Code :
  1. class TBase{};
  2.    template <class Type>
  3.    class T : public TBase
  4.    {
  5.    public:
  6.       void set(Type v){ this->v = v; }
  7.       Type get(){ return this->v; }
  8.    private:
  9.       Type v;
  10.    };
  11. int main(int argc, char** argv)
  12. {
  13.    //exemple d'utilisation d'index
  14.        
  15.    vector<TBase*> test(10);
  16.    test[0] = new T<int>();
  17.    test[1] = new T<char>();
  18.    test[2] = new T<float>();
  19.    test[0]->set(10);
  20.    cout << endl << test[0]->get() << endl;
  21.    return 0;
  22. }


Message édité par Ummon le 18-03-2004 à 11:51:43
Reply

Marsh Posté le 18-03-2004 à 11:48:36    

bah la deja a vu d'nez ton ->set va foire ,
vu qu'il nest pas declarer dans TBase

Reply

Marsh Posté le 18-03-2004 à 11:50:06    

bein c justement mon problème existentiel ^_^

Reply

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

Si tu veux faire du typage dynamique comme ça, il y a le Python qui est plus adapté que le C++. Le C++ étant un langage fortement typé ( sisi c'est vrai ), tant que tu soustype comme ça une partie de tes données ça va être le bordel.
 

Code :
  1. test[0] = new T<int>();
  2.        test[1] = new T<char>();
  3.        test[2] = new T<float>();
  4.    
  5.        static_cast<T<int>*>(test[0])->set(10);


ou

Code :
  1. T<int>* test0 = new T<int>();
  2.        test[0] = test0;
  3.        test[1] = new T<char>();
  4.        test[2] = new T<float>();
  5.    
  6.        static_cast<T<int>*>(test[0])->set(10);


Reply

Marsh Posté le 18-03-2004 à 12:07:31    

>Kristoph
Merci pour ta réponse.
Pas de Python pour moi ! Ruby forever !!!


Message édité par Ummon le 18-03-2004 à 12:09:09
Reply

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

le destructeur virtuel par pitié !

Reply

Marsh Posté le 18-03-2004 à 12:16:37    

Ummon a écrit :

>Kristoph
Merci pour ta réponse.
Pas de Python pour moi ! Ruby forever !!!


 
On va pas commencer un troll sur les langages ici. J'ai beaucoup aimé ce guide sur le Ruby qui montrait comment la syntaxe de celui-ci s'approchait du langage naturel :

Code :
  1. 5.times { print "Odelay!" }
  2. exit unless "restaurant".include? "aura"


 
Sauf que ca cafouillait des le 3eme example

Code :
  1. [toast, cheese, wine].each { |food| eat food }


 
Et après je suis arrivé sur la partie qui décrivais les differents symboles a mettre devant les variables et ça m'a rappelé le perl et le PHP alors j'ai fermé le guide et j'ai decidé de ne pas faire de Ruby :)

Reply

Marsh Posté le 18-03-2004 à 12:23:05    

en fait Ruby introduit (ca existe dans d'autres langages) la notion de bloc.

Code :
  1. ["hello", "salut", "bonjour"].each{|mot|
  2.    puts mot
  3. }


Message édité par Ummon le 18-03-2004 à 12:23:32
Reply

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

Y'en a pas mille de différents symboles (4 sauf erreur), juste pour donner un exemple, je trouve que c'est très pratique d'obliger les variables membre de commencer par un @, ça clarifie le code.
Personnellement je m'oblige à mettre 'this->' devant mes variables membre en c++ (et 'this.' en java).

Reply

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

je pense plus qu'il y a une erreur de conception a la base dans ce probleme. ptet que si tu disais ce que tu voulais faire.

Reply

Marsh Posté le 18-03-2004 à 12:40:48    

Ummon a écrit :

Y'en a pas mille de différents symboles (4 sauf erreur), juste pour donner un exemple, je trouve que c'est très pratique d'obliger les variables membre de commencer par un @, ça clarifie le code.
Personnellement je m'oblige à mettre 'this->' devant mes variables membre en c++ (et 'this.' en java).


 
Ce n'est pas l'obligation de prefixer les variables membres mais le fait d'utiliser un symbole pour ça. En Python, tu es obligé de mettre 'self.' pour acceder aux variables membres. Pas besoin de recycler un symbole n'ayant rien à voir pour faire ça.
 
Ruby me rappelle trop le perl et le php à cause de decisions de ce genre, c'est tout :)

Reply

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

Mon but est de reproduire plusieurs table (comme les tables d'une base de donnés) en mémoire avec la possibilité de créer des index pour une recherche rapide.
Il sera possible (mais je n'ai fait que des tests pour l'instant) d'ajouter, de supprimer, de modifier et de consulter les enregistrements d'une table.

Reply

Marsh Posté le 18-03-2004 à 13:21:14    

Ummon a écrit :


je trouve que c'est très pratique d'obliger les variables membre de commencer par un @, ça clarifie le code.


 
 :sweat:

Reply

Marsh Posté le 18-03-2004 à 13:23:20    

comme je dis toujours: si t'as besoin d'utiliser la notation hongroise ou de ratouter un prefixe à tes identifiants, c'est que t'es déjà perdu.

Reply

Marsh Posté le 18-03-2004 à 14:05:19    

Personnellement je trouve ca bien d'imposer des règles surtout si elles facilite la lecture. par exemple en Ruby les noms des classes doivent commencer par une majuscule.
De plus l'utilisation de symbole (@ pour les données membres en Ruby), si elle n'est pas abusive, permet une lecture et une compréhension du code plus rapide.

Reply

Marsh Posté le 18-03-2004 à 14:08:28    

non et non.

Reply

Marsh Posté le 18-03-2004 à 14:14:37    

dis-moi ce que tu penses :)

Reply

Marsh Posté le 18-03-2004 à 14:15:47    

comme taz : si tu es pas capable de savoir qui et quoi, t mal.
mes classes c'est du array pas du Array, mes membres c du data , pas de mData, data_ ou lpstrData ...

Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

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