IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

SL & STL C++ Discussion :

Utiliser une classe personnelle dans un vector


Sujet :

SL & STL C++

  1. #1
    Membre confirmé
    Avatar de Mindiell
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    735
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 735
    Points : 546
    Points
    546
    Par défaut Utiliser une classe personnelle dans un vector
    Bonsoir,

    Souhaitant utiliser une classe (mais on pourrait imaginer un type, ou une srtucture personellee aussi) dans un vector, que me faut-il au minimum pour que le vector (et après tout les list, queue, et autres map aussi) l'accepte ?

    Je pense par exemple aux constructeur et destructeur (pas obligatoire à priori), mais pour la comparaison et d'autres trucs.

    En gros, quel est le minima pour pouvoir utiliser ca avec la STL ?

    Merci,
    Mindiell
    "Souvent, femme barrit" - Elephant man

  2. #2
    Membre averti
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    258
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France, Bas Rhin (Alsace)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 258
    Points : 307
    Points
    307
    Par défaut
    Il faut qu'on puisse assigner une valeur à l'élément, cf. http://www.sgi.com/tech/stl/Assignable.html pour les conteneurs. Pour les set et les maps, il faut aussi que tu définisses un critère de tri pour le type de la clé.

  3. #3
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 614
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 614
    Points : 30 626
    Points
    30 626
    Par défaut
    Salut,

    Bien que toute la réponse se trouve dans celle de roulious, je me contenterai d'apporter quelque précisions:

    On parle souvent des "grands trois" ou des "grands quatre", qui sont, fatalement nécessaires:
    • le constructeur "classique"
    • le constructeur "par copie"
    • l'opérateur d'affectation ( operator=(type&))
    • le destructeur

    On peut aussi signaler qu'il est plus simple (pour autant que faire se puisse) d'utiliser un objet dans les conteneurs plutot qu'un pointeur sur cet objet

    Le code
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    std::vector<type> monvect;
    monvect.push_back(objmtype())
    //et plus loin
    monvect.clear();
    sera toujours plus facile à mettre au point que
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    std::vector<type*> monvect
    monvect.push_back(new type())
    //et plus loin
    for (unsigned int i=0;i<monvect.size();i++)
        delete monvect[i];
    monvect.clear();
    Mais, évidemment, il faut que ce conseil, quelque peu tranché, soit applicable dans le cadre de ce que tu fais

    Pour travailler avec les map et autres conteneurs triés, il est souvent intéressant de prévoir ce que l'on appelle un "predicat" permettant au minimum de savoir si un objet est "plus petit" qu'un autre.

    Un prédicat compris "par défaut" est le prédicat "less" qui prend une forme du genre de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
     
    class maclass
    {
        public:
           maclass();
           ~maclass();
           struct less
           {
               bool operator() (maclass& c1, maclass &c2)
               {
                   return c1<c2;//à adapter, évidemment, en fonciton de la classe
               }
           }
        //la suite
    };
    D'autres opérateurs tels que:
    • operator< (type&, type&)
    • operator> (type&, type&)
    • operator>= (type&, type&)
    • operator<= (type&, type&)
    • operator== (type&, type&)
    • operator!= (type&, type&)
    • et d'autres (opérateur de convertion, par exemple)

    ne sont pas obligatoires, mais peuvent souvent s'avérer intéressant, en fonction du but recherché
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  4. #4
    Membre averti
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    258
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France, Bas Rhin (Alsace)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 258
    Points : 307
    Points
    307
    Par défaut
    Citation Envoyé par koala01
    On parle souvent des "grands trois" ou des "grands quatre", qui sont, fatalement nécessaires:
    • le constructeur "classique"
    • le constructeur "par copie"
    • l'opérateur d'affectation ( operator=(type&))
    • le destructeur
    Ils ne sont pas forcément nécessaires. dans la mesure où ceux générés automatiquement font souvent l'affaire : si ton objet n'alloue pas de ressources à sa construction, à quoi sert un destructeur comportant juste un commentaire disant "rien à faire ici". Il en va de même pour le constructeur de copie et l'opérateur d'affectation. Si une shallow copy (je n'ai jamais croisé le terme français correspondant) suffit, autant se reposer sur le compilateur.

    Citation Envoyé par koala01
    Pour travailler avec les map et autres conteneurs triés, il est souvent intéressant de prévoir ce que l'on appelle un "predicat" permettant au minimum de savoir si un objet est "plus petit" qu'un autre.
    C'est plus qu'intéressant, c'est obligatoire, pour déclarer un conteneur trié, il faut donner le prédicat. Même si on n'en a pas l'impression, il est toujours présent, sous la forme d'un paramètre template qui vaut std::less<key_type> par défaut. Ca sera transparent pour les types de base et les std::string par exemple, mais si tu as besoin d'un set d'une classe que tu as défini, il faudra pouvoir lui donner un moyen de comparaison.

  5. #5
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 614
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 614
    Points : 30 626
    Points
    30 626
    Par défaut
    Je suis tout à fait d'accord que, si tu ne déclares pas de constructeur et/ou de destructeur, le compilateur en met des "par défaut"...

    Si, de fait, on *peut* estimer "dans certains cas" qu'il ne sert pas à grand chose de les mettre, ca ne me dérange pourtant absolument pas de les déclarer et de les définir (quitte à ce que ce soit en "inline") systématiquement (meme si je m'appuies beaucoup sur les automatisations de mon EDI)...

    Cependant, je juge personnellement plus prudent d'avoir un discours proche de
    Pensez toujours à déclarer (et à définir) vos constructeurs, destructeurs et opérateurs d'affectation, y compris quand ce n'est pas "forcément indispensable"
    plutot que d'avoir un discours du genre de
    Il n'y aura que quelques cas où les constructeurs, destructeurs et opérateurs d'affectation fournis par le compilo ne seront pas adaptés, et il faudra alors envisager de les déclarer et de les définir...
    La raison en est simple:

    Dans le premier cas, on dit "faites le toujours, meme si cela ne sert à rien (ou à pas grand chose)", alors que dans le second on commence par dire "ne le faites pas"...

    Le résultat final est que, dans le premier cas, on sera toujours dans le bon, alors que dans le second cas, on courre le risque, justement, d'être dans l'erreur (parce que l'un de ces constructeur/destructeur/opérateur d'affectation est, justement, dans un cas particulier, indispensable)...

    Ce n'est jamais que le fait de faire prendre les habitudes les meilleures possibles à ceux qui nous demandent conseil
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  6. #6
    Membre confirmé
    Avatar de Mindiell
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    735
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 735
    Points : 546
    Points
    546
    Par défaut
    Merci à tous,

    Je n'en attendais pas tant !
    Ma liste sera bien par objet direct, pas par pointeur sur ma classe. Utilisant un vector, je vais implémenter les 4 trucs de base :
    - Constructeur
    - Destructeur
    - Operateur =
    - Constructeur par copie

    Ma classe comporte elle-même une ou plusieurs listes( pas encore sur ) et d'autres petites choses.

    A propos, il serait peut-être intéressant, une fois que vous êtes d'accord sur la réponse finale (constructeur, destructuer, etc... ) , de rajouter ca dans la FAQ, non ?
    Mindiell
    "Souvent, femme barrit" - Elephant man

  7. #7
    Expert confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Décembre 2003
    Messages
    3 549
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Décembre 2003
    Messages : 3 549
    Points : 4 625
    Points
    4 625
    Par défaut
    Les conteneurs non triés nécessitent uniquement que le type soit CopyConstructible et Assignable.
    Ce qui est le cas par défaut, car le compilateur génére automatiquement un constructeur de recopie et un opérateur d'affectation.
    Il ne faut le réécrire que quand c'est nécessaire.
    Boost ftw

  8. #8
    Membre éprouvé
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    1 064
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2005
    Messages : 1 064
    Points : 1 053
    Points
    1 053
    Par défaut
    Dans certains cas d'utilisation je suppose qu'il faut aussi un constructeur par défaut. Exemple:

  9. #9
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Points : 15 920
    Points
    15 920
    Par défaut
    Dans certains cas d'utilisation je suppose qu'il faut aussi un constructeur par défaut
    Exact.

  10. #10
    Membre confirmé
    Avatar de Mindiell
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    735
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 735
    Points : 546
    Points
    546
    Par défaut
    Si vous parlez de mon cas, je vais créer les 4 fonctions (constructeur, destructeur, recopie, et assignation). Car ma classe n'a pas d'ordre de grandeur.
    Pour les constructeurs avec paramètres, j'en mettrais surement.

    A ce propos, on est d'accord que, quel que soit le nombre de constructeurs, je n'ai toujours qu'un et un seul constructeur par copie ?
    Mindiell
    "Souvent, femme barrit" - Elephant man

  11. #11
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 614
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 614
    Points : 30 626
    Points
    30 626
    Par défaut
    Citation Envoyé par Mindiell
    Si vous parlez de mon cas, je vais créer les 4 fonctions (constructeur, destructeur, recopie, et assignation). Car ma classe n'a pas d'ordre de grandeur.
    Pour les constructeurs avec paramètres, j'en mettrais surement.

    A ce propos, on est d'accord que, quel que soit le nombre de constructeurs, je n'ai toujours qu'un et un seul constructeur par copie ?
    Bien sur, vu que chaque classe n'a, théoriquement, qu'une et une seule liste de membres.

    A partir du moment où tu sais que pour la recopie, tu dois donner la valeur du membre A au membre A et celle du membre B au membre B, on voit mal comment il pourrait en etre autrement

    Evidemment, comme il y a une exception en tout, les classes template peuvent etre considérées comme exception (vue que les membres ne sont connus qu'en fonction des types que l'on déclare dans le template)...

    Mais ne dit-on pas que toute regle a une exception qui vient la confirmer
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  12. #12
    Membre confirmé
    Avatar de Mindiell
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    735
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 735
    Points : 546
    Points
    546
    Par défaut
    Citation Envoyé par zais_ethael
    Dans certains cas d'utilisation je suppose qu'il faut aussi un constructeur par défaut. Exemple:
    Tu attendrais quoi de ce genre de constructeur zais ?
    plutôt un vecteur contenant 5 machins, ou un vecteur contenant un machin initialisé avec la valeur 5 ?

    Je penche pour la première solution, mais on ne sait jamais
    Mindiell
    "Souvent, femme barrit" - Elephant man

  13. #13
    Membre éprouvé
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    1 064
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2005
    Messages : 1 064
    Points : 1 053
    Points
    1 053
    Par défaut
    Ce constructeur de la classe vector initialise la taille du vecteur avec des objets dont on va appeler automatiquement le constructeur par défaut.
    C'est l'une des raisons qui fait qu'une classe sans constructeur par défaut est énervante à manipuler.

  14. #14
    Membre confirmé
    Avatar de Mindiell
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    735
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 735
    Points : 546
    Points
    546
    Par défaut
    C'est, effectivement, une bonne idée
    A priori, mon vector initialisera les classes une par une puisque leurs données proviendront d'un fichier (au final).
    Tout comme Koala, je préfère mettre mes propres constructeurs/destructeurs plutôt que de les oublier en cas de besoin.
    Mindiell
    "Souvent, femme barrit" - Elephant man

  15. #15
    Membre éprouvé
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    1 064
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2005
    Messages : 1 064
    Points : 1 053
    Points
    1 053
    Par défaut
    Moi je préfère au contraire ne jamais avoir à en mettre, à grand coup de smart pointers, de vector pour les tableaux, de strings...
    Ca a l'énorme avantage que si tu modifies ta classe tu n'a pas à penser à modifier ton destructeur et ton opérateur de copie (ce qu'on oublie facilement), qui plus est c'est moins long.

  16. #16
    Membre confirmé
    Avatar de Mindiell
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    735
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 735
    Points : 546
    Points
    546
    Par défaut
    zais, j'ai réussi à créer ma classe, et je peux utiliser proprement la construction par défaut :
    Par contre, on est bien d'accord que ma classe ne peut pas prévoir l'utilisation de v[5] ou v[6543]. Parce qu'en essayant ca, le compilo ne me dit rien et l'affichage ne correspond logiquement à pas grand chose

    Pour le reste de mon projet, je vais l'avancer et si j'ai des questions objet, je reviendrais sur ce coin de forum : Merci à tous
    Mindiell
    "Souvent, femme barrit" - Elephant man

  17. #17
    Membre éprouvé
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    1 064
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2005
    Messages : 1 064
    Points : 1 053
    Points
    1 053
    Par défaut
    Ben si c'est prévu.
    Si tu demandes un objet se trouvant en dehors des limites du tableau tu as droit à une lancée d'exception, mais tu ne la captes peut-être pas correctement (donc tu n'affiche pas le message d'erreur).

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Utiliser une classe C++ dans un projet C++/CLI
    Par caradhras dans le forum C++/CLI
    Réponses: 4
    Dernier message: 26/06/2009, 10h37
  2. utiliser une classe c# dans un code vb.net?
    Par EternelF dans le forum VB.NET
    Réponses: 5
    Dernier message: 23/04/2009, 17h31
  3. utiliser une classe java dans une page jsp
    Par switch1 dans le forum Servlets/JSP
    Réponses: 3
    Dernier message: 16/04/2009, 16h49
  4. Comment utiliser une classe Java dans une appli PB ?
    Par bobychezA56 dans le forum Powerbuilder
    Réponses: 0
    Dernier message: 09/04/2008, 18h07
  5. [JSP] Utiliser une classe Java dans du Javascript
    Par BiM dans le forum Servlets/JSP
    Réponses: 3
    Dernier message: 11/07/2007, 11h52

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo