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 :

vector et type


Sujet :

SL & STL C++

  1. #1
    r0d
    r0d est déconnecté
    Membre expérimenté

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    4 290
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Août 2004
    Messages : 4 290
    Billets dans le blog
    2
    Par défaut vector et type
    Bonjour à tous,

    voilà, j'ai encore quelques difficultés avec le typage, et notamment les const et autres * et &. Présentement, j'ai un soucis avec un vector déclaré ainsi:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    class MaClasse
    {[...]
    std::vector<Type1*> monvector;
    };
    Dans une méthode, je reçois un objet de type Type1* que je dois insérer dans mon tableau, et je voudrais faire quelque chose du genre:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    void MaClasse::MaMethode(const Type1* pItem)
    {
        monvector.push_back(pItem);
    }
    C'est tout bête, mais ça ne compile pas. Voila l'erreur:
    cannot convert parameter 1 from 'const class Type1*' to 'class Type1*const & '
    Je ne comprends pas: il y a des *, des & et des const dans tous les sens. Auriez-vous quelques explications?

    merci

  2. #2
    Expert confirmé
    Avatar de Swoög
    Profil pro
    Inscrit en
    Janvier 2003
    Messages
    6 045
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France

    Informations forums :
    Inscription : Janvier 2003
    Messages : 6 045
    Par défaut
    Salut !

    En fait, le problème vient principalement du fait que ton vector contient des "Type1*" et que tu essaies d'y insérer un "const Type1*" le const& supplémentaire vient simplement du fait de la signature de la fonction push_back ^^

    pour résoudre ton problème, tu as deux choix, un propre, et un pas propre

    le pas propre consiste à faire un const_cast sur ton pointeur :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    void MaClasse::MaMethode(const Type1* pItem)
    {
        monvector.push_back(const_cast<Type1*>(pItem));
    }
    pas très joli n'est-ce pas

    La seconde consiste simplement à modifier un peu la signature de MaMethode pour qu'elle prenne en paramètre des "Type1*" et non des "const Type1*" :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    void MaClasse::MaMethode(Type1* pItem)
    {
        monvector.push_back(pItem);
    }
    C'est déjà nettement plus propre hein

    J'ai mentionné le premier cas uniquement parce que je sais qu'il est quelques fois possible de le rencontrer, et qu'on peut parfois passer un petit bout de temp à comprendre pourquoi il est là
    Rédacteur "éclectique" (XML, Cours PHP, Cours JavaScript, IRC, Web...)
    Les Règles du Forum - Mon Site Web sur DVP.com (Développement Web, PHP, (X)HTML/CSS, SQL, XML, IRC)
    je ne répondrai à aucune question technique via MP, MSN ou Skype : les Forums sont là pour ça !!! Merci de me demander avant de m'ajouter à vos contacts sinon je bloque !
    pensez à la balise [ code ] (bouton #) et au tag :resolu: (en bas)

  3. #3
    r0d
    r0d est déconnecté
    Membre expérimenté

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    4 290
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Août 2004
    Messages : 4 290
    Billets dans le blog
    2
    Par défaut
    Salut,

    merci pour ta réponse claire, consice et précise. Tu réponds à toutes mes questions!! :p

    Cependant, je vais malheureusement être contraint d'utiliser la première méthode que tu proposes, car je n'ai pas le droit de modifier la signature de la méthode. Il s'agit d'une méthode héritée... de loin (plusieurs étapes d'héritage), donc "pas touche"

    encore

  4. #4
    Expert confirmé
    Avatar de Swoög
    Profil pro
    Inscrit en
    Janvier 2003
    Messages
    6 045
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France

    Informations forums :
    Inscription : Janvier 2003
    Messages : 6 045
    Par défaut
    Dans ce cas, ce que je te proposerais, ce serait de rajouter une surdéfinition à MaMethode pour avoir quelque chose de ce type :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    inline void MaClasse::MaMethode(const Type1* type1) { this->MaMethode(const_cast<Type1*>(type1)); }
     
    void MaClasse::MaMethode(Type1* type1)
    {
        monvector.push_back(type1);
    }
    ça aurait au moins le mérite de montrer que tu demandes un "Type1*" et non un "const Type1*"

    par contre méfit-toi avec ces histoires de pointeurs et de const, Si jamais tu insère un objet qui DOIT être const dans ton vector et que tu l'utilises ensuite comme n'étant pas const, cela risque d'entrainer de très graves bugs !

    Je serais toi, j'esseairais plutôt de voir s'il n'est pas possible de faire autrement (par exemple pourquoi pas un vector<const Type1*> ?), parce là, il y a vraiment de gros risques de bugs selon ce que tu fais après avec les éléments de ton vector ...
    Rédacteur "éclectique" (XML, Cours PHP, Cours JavaScript, IRC, Web...)
    Les Règles du Forum - Mon Site Web sur DVP.com (Développement Web, PHP, (X)HTML/CSS, SQL, XML, IRC)
    je ne répondrai à aucune question technique via MP, MSN ou Skype : les Forums sont là pour ça !!! Merci de me demander avant de m'ajouter à vos contacts sinon je bloque !
    pensez à la balise [ code ] (bouton #) et au tag :resolu: (en bas)

  5. #5
    r0d
    r0d est déconnecté
    Membre expérimenté

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    4 290
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Août 2004
    Messages : 4 290
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par Swoög
    par contre méfit-toi avec ces histoires de pointeurs et de const, Si jamais tu insère un objet qui DOIT être const dans ton vector et que tu l'utilises ensuite comme n'étant pas const, cela risque d'entrainer de très graves bugs !
    Parfois l'informatique a un côté magique. Dans le cas présent, un mot de vient à l'esprit: divination. Serais-tu devin Swoög? Car en effet, tout content de faire tourner mon bouzin avec le const_cast<>, j'ai obtenu un joli petit bug qui fait tout planter lorsque je ferme la fenêtre sur laquelle je travaille (et qui fait partie d'une MDI avec plein de fenêtres).

    Citation Envoyé par Swoög
    Je serais toi, j'esseairais plutôt de voir s'il n'est pas possible de faire autrement (par exemple pourquoi pas un vector<const Type1*> ?), parce là, il y a vraiment de gros risques de bugs selon ce que tu fais après avec les éléments de ton vector ...
    J'y ai pensé. Le problème, c'est que j'ai vraiment besoin d'effectuer des modifications sur ces objets!

    Sinon, j'ai pensé faire un constructeur de recopie: Type1::Type1(const &Type1){}. Ca devrait marcher non?

  6. #6
    Expert confirmé
    Avatar de Swoög
    Profil pro
    Inscrit en
    Janvier 2003
    Messages
    6 045
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France

    Informations forums :
    Inscription : Janvier 2003
    Messages : 6 045
    Par défaut
    Citation Envoyé par r0d
    Parfois l'informatique a un côté magique. Dans le cas présent, un mot de vient à l'esprit: divination. Serais-tu devin Swoög? Car en effet, tout content de faire tourner mon bouzin avec le const_cast<>, j'ai obtenu un joli petit bug qui fait tout planter lorsque je ferme la fenêtre sur laquelle je travaille
    Je suis pas devin, mais j'ai déjà eu à faire avec const_cast, j'ai eu droit à des beaux petits feux d'artifices de segfault (entre autres)

    Le constructeur de copie n'y est pour rien, tu stockes des pointeurs, donc le constructeur de copie ne sera même pas appellé... par contre, tu peux tout à fait faire un vector<Type1> mais dans ce cas, tous les éléments seront dupliqués, et donc tu perdras certains avantages inhérents aux pointeurs (le fait que tu manipule justement l'objet pointé ). Sauf si ta classe Type1 manipule des pointeurs en son sein, auquel cas le constructeur par recopie est OBLIGATOIRE tout comme le destructeur et l'opérateur = pour éviter des segfaut et autres memoryhole (CF FAQ, mais je sais plus quel article, je crois que ça parle de forme canonique d'une classe ou un truc comme ça moi et la théorie ^^), indépendament du problème en cours

    Sinon, je dirais que ça doit relever d'un problème de modélisation...
    Ne peux-tu couper en deux ton vector ? en mettant d'un côté les "const Type1*" et de l'autre les "Type1*" ? N'y a-t-il pas méprise à un moment dans ta modélisation ?

    Car il est très surprenant que ça t'oblige à modifier des éléments const...
    Rédacteur "éclectique" (XML, Cours PHP, Cours JavaScript, IRC, Web...)
    Les Règles du Forum - Mon Site Web sur DVP.com (Développement Web, PHP, (X)HTML/CSS, SQL, XML, IRC)
    je ne répondrai à aucune question technique via MP, MSN ou Skype : les Forums sont là pour ça !!! Merci de me demander avant de m'ajouter à vos contacts sinon je bloque !
    pensez à la balise [ code ] (bouton #) et au tag :resolu: (en bas)

  7. #7
    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 : 41
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Par défaut
    Au contraire rien de magique, tu as un problème de conception qui n'a pas 50 solutions. Soit prendre en paramètre ce que tu stockes dans ton vecteur, soit stocker dans ton vecteur ce que tu prends en paramètre. Quoique tu tentes d'autre, ce sera de la bidouille.

  8. #8
    r0d
    r0d est déconnecté
    Membre expérimenté

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    4 290
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Août 2004
    Messages : 4 290
    Billets dans le blog
    2
    Par défaut
    Je pense que je me suis mal expliqué.
    En fait, le "noyau" de l'application contient une map (std::map) de Type1. Et ça, interdit d'y toucher, pour diverses raisons, mais c'est normal et c'est le mieux pour tout le monde.
    Du coup, grâce à cette petite discution (merci encore) j'ai compris que je n'ai d'autre choix que de dupliquer ceux dont j'ai besoin (et que je reçois via la méthode dont j'ai parlé au début).
    D'où la necessité d'un constructeur de recopie.
    En fait, je pense que je vais utilser vector<Type1> et implémenter un constructeur de recopie et un operateur =. Mais bon, je t'explique pas la galère: la classe est énorme

  9. #9
    Expert confirmé
    Avatar de Swoög
    Profil pro
    Inscrit en
    Janvier 2003
    Messages
    6 045
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France

    Informations forums :
    Inscription : Janvier 2003
    Messages : 6 045
    Par défaut
    Citation Envoyé par r0d
    En fait, je pense que je vais utilser vector<Type1> et implémenter un constructeur de recopie et un operateur =. Mais bon, je t'explique pas la galère: la classe est énorme
    Voilà pourquoi quand on crée une classe il faut toujours (disons plutôt "le plus souvent") implémenter directement constructeur de copie, destructeur et opérateur =
    Rédacteur "éclectique" (XML, Cours PHP, Cours JavaScript, IRC, Web...)
    Les Règles du Forum - Mon Site Web sur DVP.com (Développement Web, PHP, (X)HTML/CSS, SQL, XML, IRC)
    je ne répondrai à aucune question technique via MP, MSN ou Skype : les Forums sont là pour ça !!! Merci de me demander avant de m'ajouter à vos contacts sinon je bloque !
    pensez à la balise [ code ] (bouton #) et au tag :resolu: (en bas)

  10. #10
    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 : 41
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Par défaut
    Note aussi qu'une classe ne devrait jamais gérer plus d'une ressource brute, càd que la rendre copiable devrait toujours être trivial.

  11. #11
    Rédacteur

    Avatar de Matthieu Brucher
    Profil pro
    Développeur HPC
    Inscrit en
    Juillet 2005
    Messages
    9 810
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Développeur HPC
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2005
    Messages : 9 810
    Par défaut
    Citation Envoyé par r0d
    Je pense que je me suis mal expliqué.
    En fait, le "noyau" de l'application contient une map (std::map) de Type1. Et ça, interdit d'y toucher, pour diverses raisons, mais c'est normal et c'est le mieux pour tout le monde.
    Du coup, grâce à cette petite discution (merci encore) j'ai compris que je n'ai d'autre choix que de dupliquer ceux dont j'ai besoin (et que je reçois via la méthode dont j'ai parlé au début).
    D'où la necessité d'un constructeur de recopie.
    En fait, je pense que je vais utilser vector<Type1> et implémenter un constructeur de recopie et un operateur =. Mais bon, je t'explique pas la galère: la classe est énorme
    Ta map, c'est une map de quoi ?? C'est bizarre, parce qu'OK, on a pas le droit de modifier la clé, mais l'autre paramètre si - du moins à ma connaissance -

  12. #12
    Membre émérite Avatar de reggae
    Profil pro
    Inscrit en
    Août 2005
    Messages
    773
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Août 2005
    Messages : 773
    Par défaut
    Cependant, je vais malheureusement être contraint d'utiliser la première méthode que tu proposes, car je n'ai pas le droit de modifier la signature de la méthode.

    Tu peux ajouter dans ta classe une fonction qui contient ce code:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
        monvector.push_back(type1);
    qui est appelée par ta méthode MaClasse::MaMethode...
    Ceci afin de te faciliter la vie.

  13. #13
    r0d
    r0d est déconnecté
    Membre expérimenté

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    4 290
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Août 2004
    Messages : 4 290
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par Loulou24
    Note aussi qu'une classe ne devrait jamais gérer plus d'une ressource brute, càd que la rendre copiable devrait toujours être trivial.
    Que veux-tu dire par "une ressource brute"?
    Ma classe correspond à une ligne d'un tableau qui comprend environ 40 colonnes. Il y a de tout: string, long, double, bool, image et même des objets. Je ne peux pas vraiment l'exploser car j'utilise un template de tableau qui prend cette classe en paramètre pour les méthodes Add, Delete, etc. En fait, créer le constucteur de recopie pour cette classe n'est pas difficle, mais long. Et puis le problème c'est qu'elle hérite des plusieurs autres classes qui contiennent chacune d'autres variables membres...

    Citation Envoyé par Miles
    Ta map, c'est une map de quoi ?? C'est bizarre, parce qu'OK, on a pas le droit de modifier la clé, mais l'autre paramètre si - du moins à ma connaissance -
    En fait, le truc c'est que je ne reçois que des éléments (second) de cette map. Et je les reçois en const.

  14. #14
    Expert confirmé
    Avatar de Swoög
    Profil pro
    Inscrit en
    Janvier 2003
    Messages
    6 045
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France

    Informations forums :
    Inscription : Janvier 2003
    Messages : 6 045
    Par défaut
    En toutes logique, si ta classe ne contient pas de pointeurs, ou autres ressources nécessitant une allocation dynamique (ie ressource brute)... alors t'as classe n'as LOGIQUEMENT pas besoin d'un constructeur de copie défini explicitement celui par défaut généré par le compilateur suffit amplement, ensuite, c'est vrai que c'est toujours plus propre
    Rédacteur "éclectique" (XML, Cours PHP, Cours JavaScript, IRC, Web...)
    Les Règles du Forum - Mon Site Web sur DVP.com (Développement Web, PHP, (X)HTML/CSS, SQL, XML, IRC)
    je ne répondrai à aucune question technique via MP, MSN ou Skype : les Forums sont là pour ça !!! Merci de me demander avant de m'ajouter à vos contacts sinon je bloque !
    pensez à la balise [ code ] (bouton #) et au tag :resolu: (en bas)

  15. #15
    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 : 41
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Par défaut
    Effectivement, c'est ça que je voulais dire. Si ta classe ne gère aucune ressource brute (ie. pas trivialement copiable), alors tu n'as pas besoin de redéfinir un constructeur par copie, celui du compilo fera l'affaire.

  16. #16
    Rédacteur

    Avatar de Matthieu Brucher
    Profil pro
    Développeur HPC
    Inscrit en
    Juillet 2005
    Messages
    9 810
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Développeur HPC
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2005
    Messages : 9 810
    Par défaut
    Pourquoi stocker les éléments en const dans la map ?? C'ets vraiment bizarre comme manière de faire... Tu ne peux pas le faire sauter discrètement ?

  17. #17
    r0d
    r0d est déconnecté
    Membre expérimenté

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    4 290
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Août 2004
    Messages : 4 290
    Billets dans le blog
    2
    Par défaut
    okay, merci pour vos précisions, j'en avais bien besoin
    grâce à vous, je comble mes lacunes progressivement et qui sait, peut-être un jour serais-je un bon développeur?

    Bon week-end!

  18. #18
    r0d
    r0d est déconnecté
    Membre expérimenté

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    4 290
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Août 2004
    Messages : 4 290
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par Miles
    Pourquoi stocker les éléments en const dans la map ?? C'ets vraiment bizarre comme manière de faire... Tu ne peux pas le faire sauter discrètement ?
    Ok, je vais essayer...

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

Discussions similaires

  1. affichier un vector de type cvPoint2D32f
    Par syki.mail dans le forum C++
    Réponses: 5
    Dernier message: 31/08/2013, 21h40
  2. Réponses: 11
    Dernier message: 15/02/2011, 17h25
  3. [STL]vector de type composé et fonction sort
    Par LordBob dans le forum SL & STL
    Réponses: 14
    Dernier message: 21/03/2007, 11h56
  4. Pb de conversion: double[] vers un vector type???
    Par hycsos dans le forum SL & STL
    Réponses: 4
    Dernier message: 15/01/2006, 07h59
  5. variable type tableau (vector) statique / constants
    Par Kaktus dans le forum SL & STL
    Réponses: 5
    Dernier message: 13/10/2005, 22h46

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