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

C++ Discussion :

Problème de pointeur dans un vecteur


Sujet :

C++

  1. #1
    Membre éclairé
    Homme Profil pro
    Fondateur
    Inscrit en
    Octobre 2002
    Messages
    445
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Fondateur
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Octobre 2002
    Messages : 445
    Par défaut Problème de pointeur dans un vecteur
    Bonjour,

    J'ai un petit problème avec un vecteur de pointeurs.

    Voici le code qui pose problème : (j'ai volontairement vidé les classes et mis tout ensemble pour bien isoler le problème)

    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
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
     
    #include <iostream>
    #include <vector>
     
    using namespace std;
     
    class Element{
    	public :
    		string att1;
    };
     
    class Constante : public Element
    {
    	public :
    		string att2;
    };
     
     
    int main()
    {	
    	vector<Element*>* v = new vector<Element*>;
    	Element* elt = new Element();	
    	v->insert(elt);
                 // Constante* cte = new Constante();
                 // v->insert(cte);
     
     
     
    	return 0;
    }
    Lorsque je compile, g++ me dit en gros qu'il ne s'attend pas à avoir ce type lors de l'insertion dans le vecteur.

    Pourtant mon vecteur est bien un vecteur de pointeurs sur la classe Element.

    Quelqu'un saurait d'où cela peut venir ?

    Ma deuxième question concerne ce que j'ai mis en commentaire dans le code. L'insertion d'un pointeur sur la classe Constante est elle possible dans le vecteur compte tenu du fait que Constante hérite de Element ?

  2. #2
    Membre confirmé
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    124
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2007
    Messages : 124
    Par défaut
    peux tu copier-coller l'erreur qu'il affiche stp?

  3. #3
    Membre émérite

    Profil pro
    Inscrit en
    Septembre 2006
    Messages
    717
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2006
    Messages : 717
    Par défaut
    La fonction insert() s'utilise avec plusieurs arguments pour insérer un ou plusieurs éléments à une certaine position dans le vecteur. Pour ajouter un élément à la fin, c'est push_back().

  4. #4
    Membre éclairé
    Homme Profil pro
    Fondateur
    Inscrit en
    Octobre 2002
    Messages
    445
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Fondateur
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Octobre 2002
    Messages : 445
    Par défaut
    Citation Envoyé par Sylvain Togni Voir le message
    La fonction insert() s'utilise avec plusieurs arguments pour insérer un ou plusieurs éléments à une certaine position dans le vecteur. Pour ajouter un élément à la fin, c'est push_back().
    Effectivement ça marche, j'ai pas assez regardé la doc. Merci.

  5. #5
    Membre émérite

    Profil pro
    Inscrit en
    Septembre 2006
    Messages
    717
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2006
    Messages : 717
    Par défaut
    L'insertion d'un pointeur sur la classe Constante est elle possible dans le vecteur compte tenu du fait que Constante hérite de Element ?
    Oui, c'est le principe même du polymorphisme de classe, un pointeur (ou référence) vers un objet dérivé peut être utilisé partout où un pointeur (ou référence) vers un objet de base est attendu.

  6. #6
    Membre éclairé Avatar de befalimpertinent
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    561
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Gironde (Aquitaine)

    Informations forums :
    Inscription : Avril 2007
    Messages : 561
    Par défaut
    Pourquoi un pointeur sur le vecteur ? Ne peux tu pas faire simplement :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    int main()
    {	
    	vector<Element*> v;
    	Element* elt = new Element();	
    	v.push_back(elt);
            Constante* cte = new Constante();
            v.push_back(cte);
     
    	return 0;
    }
    Ma deuxième question concerne ce que j'ai mis en commentaire dans le code. L'insertion d'un pointeur sur la classe Constante est elle possible dans le vecteur compte tenu du fait que Constante hérite de Element ?
    Oui, par polymorphisme cf FAQ pour plus de renseignements

  7. #7
    Membre éprouvé
    Inscrit en
    Mai 2007
    Messages
    157
    Détails du profil
    Informations personnelles :
    Âge : 43

    Informations forums :
    Inscription : Mai 2007
    Messages : 157
    Par défaut
    en effet insert s'utilise avec insert(position, iteration, valeur)
    dans ton cas il faudrait faire par exemple

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    v->insert(v->end(),1,elt);

  8. #8
    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
    Par défaut
    Les variables intermédiaires elt et cte ne servent à rien.
    Ensuite, ce genre de chose reste une erreur de conception. Qui se charge de gérer la durée de vie des objets dynamiquement alloués ?

  9. #9
    Membre éclairé
    Homme Profil pro
    Fondateur
    Inscrit en
    Octobre 2002
    Messages
    445
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Fondateur
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Octobre 2002
    Messages : 445
    Par défaut
    Citation Envoyé par befalimpertinent Voir le message
    Pourquoi un pointeur sur le vecteur ? Ne peux tu pas faire simplement :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    int main()
    {	
    	vector<Element*> v;
    	Element* elt = new Element();	
    	v.push_back(elt);
            Constante* cte = new Constante();
            v.push_back(cte);
     
    	return 0;
    }


    Oui, par polymorphisme cf FAQ pour plus de renseignements

    L'exemple de code que j'ai mis est hors contexte.
    Dans mon code complet, je crée ce vecteur au sein d'une méthode et je le renvoie en sortie de la méthode.
    Pour pouvoir y accéder à l'extérieur il me fallait donc plutôt un pointeur.

    Peut-être qu'utiliser une référence est préférable dans ce cas là ? mais ne connaissant pas trop bien le C++, j'ai mis un pointeur comme j'aurais fait en C en fait.

  10. #10
    Membre éclairé
    Homme Profil pro
    Fondateur
    Inscrit en
    Octobre 2002
    Messages
    445
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Fondateur
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Octobre 2002
    Messages : 445
    Par défaut
    Citation Envoyé par loufoque Voir le message
    Les variables intermédiaires elt et cte ne servent à rien.
    Ensuite, ce genre de chose reste une erreur de conception. Qui se charge de gérer la durée de vie des objets dynamiquement alloués ?

    Effectivement les variables intermédiaires ne servent à rien mais pour montrer un problème j'ai sorti l'erreur de mon code et j'ai fait en sorte de rendre ce bout de code le plus explicite possible.

    Le problème avec mon vecteur c'est que je le crée à l'intérieur d'une méthode et ensuite je le renvoie.

    Au départ, je ne comptais faire qu'un pointeur sur un vecteur pour pouvoir le renvoyer et ensuite y accéder mais je me suis demander si les objets que je mettrais dans ce vecteur seraient accessibles à l'extérieur si je ne mettais pas des pointeurs.

  11. #11
    Membre éclairé Avatar de befalimpertinent
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    561
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Gironde (Aquitaine)

    Informations forums :
    Inscription : Avril 2007
    Messages : 561
    Par défaut
    Citation Envoyé par sylsau Voir le message
    Au départ, je ne comptais faire qu'un pointeur sur un vecteur pour pouvoir le renvoyer et ensuite y accéder mais je me suis demander si les objets que je mettrais dans ce vecteur seraient accessibles à l'extérieur si je ne mettais pas des pointeurs.
    Non pour pouvoir utiliser le polymorphisme tu dois obligatoirement passer par des pointeurs ou des références.

    En revanche ce que souligne loufoque est que tu dois t'occuper de gérer correctement la mémoire (smart pointeur de Boost, compteur de référence) sous peine d'avoir des surprises si un des pointeurs de ton vecteur est supprimer en dehors de tout contrôle. Dans ce cas ta méthode pour vider ton vecteur (cf FAQ http://c.developpez.com/faq/cpp/inde...elete_sequence
    risque d'avoir quelques soucis )
    Si tu ne veux pas t'embêter avec tout ça tu dois au moins être sur qu'aucun delete ne sera fait sur un des éléments du vecteur avant que tu le vides avec la méthode approprié. Et que une fois vider tu sois sur de ne plus accéder à ces éléments.

  12. #12
    Membre éclairé
    Homme Profil pro
    Fondateur
    Inscrit en
    Octobre 2002
    Messages
    445
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Fondateur
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Octobre 2002
    Messages : 445
    Par défaut
    Citation Envoyé par befalimpertinent Voir le message
    Non pour pouvoir utiliser le polymorphisme tu dois obligatoirement passer par des pointeurs ou des références.

    En revanche ce que souligne loufoque est que tu dois t'occuper de gérer correctement la mémoire (smart pointeur de Boost, compteur de référence) sous peine d'avoir des surprises si un des pointeurs de ton vecteur est supprimer en dehors de tout contrôle. Dans ce cas ta méthode pour vider ton vecteur (cf FAQ http://c.developpez.com/faq/cpp/inde...elete_sequence
    risque d'avoir quelques soucis )
    Si tu ne veux pas t'embêter avec tout ça tu dois au moins être sur qu'aucun delete ne sera fait sur un des éléments du vecteur avant que tu le vides avec la méthode approprié. Et que une fois vider tu sois sur de ne plus accéder à ces éléments.
    C'est bien ce qui me semblait pour le polymorphisme.

    Lorsque je récupère les éléments de mon vecteur, comment je peux déterminer le type de l'élément ? En Java, j'aurais utilisé l'opérateur "instance of" mais là je ne vois pas trop.

    J'ai bien essayé avec dynamic_cast mais cela ne marche pas. Le compilateur me disant qu'il n'est pas possible de convertir un Element* en Constante*.

  13. #13
    Membre éclairé Avatar de befalimpertinent
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    561
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Gironde (Aquitaine)

    Informations forums :
    Inscription : Avril 2007
    Messages : 561
    Par défaut
    c'est pourtant bien un dynamic_cast qu'il faut utiliser dans ce cas il me semble. Montre le code que tu as utilisé

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

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    4 301
    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 301
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par sylsau Voir le message
    Lorsque je récupère les éléments de mon vecteur, comment je peux déterminer le type de l'élément ? En Java, j'aurais utilisé l'opérateur "instance of" mais là je ne vois pas trop.
    Il est impossible de faire cela en C++. Enfin pas que je sache. Et en fait, je ne comprend pas pourquoi on pourrait en avoir besoin. C'est le principe même du polymorphisme: tu utilises des objets sans savoir exactement ce que c'est, juste en connaissant leur interface. Cela reviendrait à implémenter une propriété GetType dans chaque classe qui te renvoie le type de la classe.

  15. #15
    Membre éclairé Avatar de befalimpertinent
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    561
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Gironde (Aquitaine)

    Informations forums :
    Inscription : Avril 2007
    Messages : 561
    Par défaut
    Citation Envoyé par r0d Voir le message
    C'est le principe même du polymorphisme: tu utilises des objets sans savoir exactement ce que c'est, juste en connaissant leur interface. Cela reviendrait à implémenter une propriété GetType dans chaque classe qui te renvoie le type de la classe.
    Exact il est vrai que le down_casting est plutôt à éviter et que bien souvent on préfèrera l'utilisation de la virtualité qui peut résoudre élégamment ce type de problème. A vrai dire il me semble que les seules fois où j'utilise le dynamic_cast c'est quand j'accède à des objets d'une bibliothèque extérieur.

  16. #16
    screetch
    Invité(e)
    Par défaut
    je trouve que le dynamic_cast c'est le mal.


    Exemple : des gens proposaient de faire une classe "FichierOuRepertoire" puis de la specialiser en "Fichier" et "Repertoire". Un repertoire contient un membre "contenu" qui est une liste de FichierOuRepertoire.

    Si bien que pour 80% des methodes, tu devais demander si ce que tu avais trouve etait un fichier ou un repertoire.

    Il aurait ete plus judicieux (apres ca depend de läutilisation mais dns ce cas la c'etait vrai" de fair deux classes disjointes, Fichier et Repertoire, un Repertoire contenant deux membres : une liste de Repertoire (soirt sous repertoire) et une liste de Fichier.

    Ainsi tu sais precisement ce que tu recuperes, tu n'as pas besoin de demander son type.



    Pour un truc que j'ai vu plus haut, on ne peut pas retrouver le type a partir de la classe de base mais on peut faire des essais : en effet dynamic_cast renvoie un nouveau pointeur si ca a marche et il renvoie 0 si ca ne marche pas. Donc avec des essais... on peut faire un switch/case moche. mais utiliser dynamic_cast pour retrouver l'objet original en general c'est moche.



    Pour ton probleme (le fait que dynamic_cast ne compile pas) c'est sans dote du au fait que dynamic-cast n'a pas acces a la hierarchie de classe. Pour que ynamic_cast fonctionne, il doit avoir la definition complete des deux classes (pour bien voir qu'elles sont parentes).
    Peut etre as tu juste predeclaré tes classes au lieu d'inclure le fichier en-tete ?

  17. #17
    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
    Par défaut
    orsque je récupère les éléments de mon vecteur, comment je peux déterminer le type de l'élément ? En Java, j'aurais utilisé l'opérateur "instance of" mais là je ne vois pas trop.
    dynamic_cast c'est exactement la même chose que instanceof de Java.

    À part ça, tes types doivent être polymorphes pour que dynamic_cast fonctionne (bien évidemment, ça ne peut pas fonctionner simplement avec de la magie vodoo).

  18. #18
    Membre éclairé
    Homme Profil pro
    Fondateur
    Inscrit en
    Octobre 2002
    Messages
    445
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Fondateur
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Octobre 2002
    Messages : 445
    Par défaut
    Citation Envoyé par befalimpertinent Voir le message
    Exact il est vrai que le down_casting est plutôt à éviter et que bien souvent on préfèrera l'utilisation de la virtualité qui peut résoudre élégamment ce type de problème. A vrai dire il me semble que les seules fois où j'utilise le dynamic_cast c'est quand j'accède à des objets d'une bibliothèque extérieur.
    C'est ce que j'ai fait en rajoutant une méthode indiquant le type de l'objet comme cela est décrit dans la faq c++.

    Mais une fois que j'ai le type je suis bien obligé de faire un cast quand même ! Je ne vois pas quelle solution peut être meilleure, si y en a une ça m'intéresserait que vous m'en disiez plus.

  19. #19
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 5 463
    Par défaut
    Citation Envoyé par sylsau Voir le message
    C'est ce que j'ai fait en rajoutant une méthode indiquant le type de l'objet
    Donc tu es en train de te fabriquer ton dynamic_cast à toi, plutôt que d'utiliser celui standard qui lui marchera dans tous les cas...

    Ce n'est pas dynamic_cast qui est douteux, c'est de faire un traitement différent selon le type de l'objet, alors que le but du polymorphisme est de gommer des différences d'implémentation sous une interface commune.
    Ma session aux Microsoft TechDays 2013 : Développer en natif avec C++11.
    Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
    Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage à la découverte d'un nouveau monde
    Je donne des formations au C++ en entreprise, n'hésitez pas à me contacter.

  20. #20
    Alp
    Alp est déconnecté
    Expert confirmé

    Avatar de Alp
    Homme Profil pro
    Inscrit en
    Juin 2005
    Messages
    8 575
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Juin 2005
    Messages : 8 575
    Par défaut
    Citation Envoyé par befalimpertinent Voir le message
    Exact il est vrai que le down_casting est plutôt à éviter et que bien souvent on préfèrera l'utilisation de la virtualité qui peut résoudre élégamment ce type de problème. A vrai dire il me semble que les seules fois où j'utilise le dynamic_cast c'est quand j'accède à des objets d'une bibliothèque extérieur.
    Et encore ... On a souvent un moyen de contourner ça.
    De plus, le polymorphisme, c'est quand on doit traiter un ensemble d'éléments de la même manière en surface, et pendant ce temps eux agissent différemment au fond, selon leur type.

    Downcaster va à l'encontre de cela. Sauf dans des cas très rares, je ne downcast pas.

Discussions similaires

  1. Problèmes de redondances dans un vecteur
    Par le.nono dans le forum Débuter avec Java
    Réponses: 3
    Dernier message: 25/02/2012, 09h21
  2. Trie de pointeurs dans un vecteur
    Par toams69 dans le forum C++
    Réponses: 5
    Dernier message: 23/09/2009, 10h05
  3. Réponses: 6
    Dernier message: 17/07/2008, 18h10
  4. Problème sur un pointeur dans une structure
    Par steph_1 dans le forum Langage
    Réponses: 5
    Dernier message: 05/09/2007, 18h59
  5. Problème d'heritage dans vecteur
    Par coco-loco dans le forum Langage
    Réponses: 3
    Dernier message: 07/02/2007, 11h28

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