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 :

Probleme d'acces sur un vecteur contenant des pointeurs sur pointeur


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Juin 2010
    Messages
    24
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2010
    Messages : 24
    Par défaut Probleme d'acces sur un vecteur contenant des pointeurs sur pointeur
    Bonjour,

    Je suis un peu perdu avec un programme dans lequel j'utilise des vecteurs de pointeurs. Je tente inlassablement de jouer avec les pointeurs depuis des heures, mais je ne trouve pas de solution.

    Le programme me sert d'entrainement pour vérifier que j'ai bien retenu mes leçons de c++, il s'agit d'une liste d'ami.
    Dans un vecteur j'enregistre des gens : titi, toto etc..
    Dans un autre vecteur, j'enregistre les amis de ces gens. (On est ami avec soit même).

    J'ai commenté le programme dans le main pour vous expliquer son déroulement. La ligne bloquante est celle où je tente d'accéder au propriété de mon objet Personne.

    Merci d'avance pour votre aide et vos indications.


    Classe Personne
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    #include <string>
     
    class Personne {
        public:
        Personne() {}
        Personne(std::string n) : name(n), firstname("") {}
        ~Personne() {}
        std::string name;
        std::string firstname;
    };
    Classe de liste des amis
    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
    31
    32
    33
    34
    35
    36
    37
    38
    39
    #include <iostream>
    #include <string>
    #include <vector>
    #include "personne.h"
     
    class FriendList {
        public:
        FriendList() {}
        FriendList(std::string n) : name(n) {}
        ~FriendList() {}
        std::string getName();
        void setName(std::string n);
        void FriendList::addPerson(Personne* &p);
        std::vector<Personne**> FriendList::listInvited();
     
        private:
        std::string name;
        std::vector<Personne**> vInvited;
    };
     
    // Fichier CPP ci-dessous
     
    #include "FriendList.h"
     
    std::string FriendList::getName(){
        return(name);
    }
     
    void FriendList::setName(std::string n){
        name = n;
    }
     
    void FriendList::addPerson(Personne* &p){
        vInvited.push_back(&p);
    }
     
    std::vector<Personne**> FriendList::listInvited(){
        return(vInvited);
    }
    Le Main
    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
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    #include <iostream>
    #include "personne.h"
    #include "FriendList.h"
    #include <vector>
     
    using namespace std;
     
    vector<Personne*> vectorPerson;
    vector<FriendList*> vectorFriendList;
     
    int main()
    {
        Personne p1("toto");
        vectorPerson.push_back(&p1); // une personne toto est ajoutee
     
        FriendList f1("listeDeToto");
        vectorFriendList.push_back(&f1); // la liste de toto est créée
     
        vectorFriendList[0]->addPerson(vectorPerson[0]); // toto est ami avec lui meme
     
        Personne p2("titi");
        vectorPerson.push_back(&p2); // une personne titi est ajoutee
     
        vectorPerson[0]->name = "tutu"; // on renomme titi en tutu
     
        vectorFriendList[0]->addPerson(vectorPerson[1]); // j'ajoute titi a la liste de toto (devenu tutu)
     
     
    // le listing des personnes (tutu et titi)
        for(int i=0; i<vectorPerson.size(); i++){
            cout << vectorPerson[i]->name << endl;
        }
     
    // le listing des listes dami
        for(int i=0; i<vectorFriendList.size(); i++){
            cout << endl << vectorFriendList[i]->getName() << ":" << endl;
     
            // la liste dami de la personne        
            vector<Personne**> vFriendsDeTutu  = vectorFriendList[i]->listInvited();
            cout << endl << vFriendsDeTutu.size() << " personne dont :" << endl;
            for(int j=0; j<vFriendsDeTutu.size(); j++){
            // plantage ici
            //            cout << *vFriendsDeTutu[j]->name << ":" << endl;
            }
        }
     
        return 0;
    }

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

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    4 292
    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 292
    Billets dans le blog
    2
    Par défaut
    Bonjour,

    avant toute autre considération, une question: pourquoi utilises-tu un vecteur de pointeurs de pointeurs? Pourquoi ne pas utiliser un simple vector<Personne> (sans pointeurs)?

  3. #3
    Membre expérimenté
    Avatar de Chatanga
    Profil pro
    Inscrit en
    Décembre 2005
    Messages
    211
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2005
    Messages : 211
    Par défaut
    Citation Envoyé par Logan5 Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    for(int j=0; j<vFriendsDeTutu.size(); j++){
        // plantage ici
        cout << *vFriendsDeTutu[j]->name << ":" << endl;
    }
    Pour que ça plante (et ça plantera), il faut déjà mettre des parenthèses autour de "*vFriendsDeTutu[j]" :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    for(int j=0; j<vFriendsDeTutu.size(); j++){
        // plantage ici
        cout << (*vFriendsDeTutu[j])->name << ":" << endl;
    }
    Une fois cette correction faite, la raison du plantage résidera dans la double indirection de "std::vector<Personne**>" qui, par ailleurs, ne te sert à rien. C'est de pointer sur des instance de Personne qui t'intéresse ici, pas de pointer sur une variable temporaire (retournée par l'opérateur [] de vector) qui pointe à son tour sur une personne.

  4. #4
    Membre averti
    Profil pro
    Inscrit en
    Juin 2010
    Messages
    24
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2010
    Messages : 24
    Par défaut
    Tout d'abord merci pour vos réponses. J'en suis venu à mettre des pointeurs, puis des pointeurs sur pointeur car je n'obtenais pas le resultat voulu. Et effectivement, j'ai complètement perdu mon objectif de vue.

    @r0d J'ai suivi ton conseil, mais lorsque je change le nom de titi pour tutu, dans mon vecteur, la modification "ne suis pas". Par contre, ça compile bien !

    @Chatanga Effectivement je veux pointer sur les instances des personnes afin de suivre les changements effectués sur les noms comme juste au dessus.

    Tel quel, j'ai bien compris que cette ligne effectue une copie de mon objet Personne. Et du coup je suis tenté de remettre des pointeurs. Mais j'ai l'impression de tourner en rond

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    vectorFriendList[0].addPerson(vectorPerson[0]);

    FriendList modifiée
    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
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    #ifndef FriendList_H_INCLUDED
    #define FriendList_H_INCLUDED
     
    #include <iostream>
    #include <string>
    #include <vector>
    #include "personne.h"
     
    class FriendList {
        public:
        FriendList() {}
        FriendList(std::string n) : name(n) {}
        ~FriendList() {}
        std::string getName();
        void setName(std::string n);
        void FriendList::addPerson(Personne p);
        std::vector<Personne> FriendList::listInvited();
     
        private:
        std::string name;
        std::vector<Personne> vInvited;
    };
     
    #endif // FriendList_H_INCLUDED
     
    // le CPP
     
    #include "FriendList.h"
     
     
     
    std::string FriendList::getName(){
        return(name);
    }
     
    void FriendList::setName(std::string n){
        name = n;
    }
     
    void FriendList::addPerson(Personne p){
        vInvited.push_back(p);
    }
     
    std::vector<Personne> FriendList::listInvited(){
        return(vInvited);
    }
    Main modifié
    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
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    #include <iostream>
    #include "personne.h"
    #include "FriendList.h"
    #include <vector>
     
    using namespace std;
     
    vector<Personne> vectorPerson;
    vector<FriendList> vectorFriendList;
     
    int main()
    {
        Personne p1("toto");
        vectorPerson.push_back(p1);
        FriendList f1("listeDeToto");
        vectorFriendList.push_back(f1);
     
        vectorFriendList[0].addPerson(vectorPerson[0]);
     
     
        Personne p2("titi");
        vectorPerson.push_back(p2);
        vectorPerson[0].name = "tutu";
     
     
        vectorFriendList[0].addPerson(vectorPerson[1]);
     
        for(int i=0; i<vectorPerson.size(); i++){
            cout << vectorPerson[i].name << endl;
        }
     
        for(int i=0; i<vectorFriendList.size(); i++){
            cout << endl << vectorFriendList[i].getName() << ":" << endl;
            vector<Personne> vFriendsDeTutu  = vectorFriendList[i].listInvited();
            cout << endl << vFriendsDeTutu.size() << " personne dont :" << endl;
            for(int j=0; j<vFriendsDeTutu.size(); j++){
                cout << vFriendsDeTutu[j].name << endl;
            }
        }
     
        return 0;
    }

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

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    4 292
    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 292
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par Logan5 Voir le message
    Tel quel, j'ai bien compris que cette ligne effectue une copie de mon objet Personne. Et du coup je suis tenté de remettre des pointeurs. Mais j'ai l'impression de tourner en rond
    C'est la raison pour laquelle je te demandais pourquoi tu utilisais des pointeurs. Posée de façon plus abrupte, la question est: "est-ce que tu sais ce que tu es en train de faire?". Est-ce que tu sais à quel résultat veux-tu arriver?
    Il est absolument primordial que tu aies une idée la plus claire possible du résultat que tu souhaites obtenir avant de te lancer dans l'écriture du code, car sinon, tu va finir par tourner en rond...

    Par exemple, dans ton cas, il faut que tu décides qui sera responsable des Personne. Cela signifie qu'il faut que tu décides quand et par qui les objets Personne vont-ils être construit, et quand et par qui vont-il être détruits.

    Lorsqu'on programme en c++ il faut faire particulièrement attention à ce qui se passe en mémoire, et donc il faut toujours savoir, avant d'écrire le code, une idée du cycle de vie des objets.

    Une fois que tu auras répondu à cette question, viens la question de la manière de stocker les objets. L'utilisation de pointeurs peut être légitime, ou pas, selon ce que tu souhaites faire. Mais garde à l'esprit que si tu peux, évite l'utilisation de pointeur.

    Une chose à savoir aussi: la copie d'un objet simple est à peine plus gourmand qu'une copie de pointeurs. Dans un contexte où la rapidité d'exécution n'est pas primordiale, la différence peut être considérée comme négligeable.

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

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    4 292
    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 292
    Billets dans le blog
    2
    Par défaut
    Tiens, il y a dans ton code un exemple parfait de ce que je suis en train d'essayer d'expliquer:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    void FriendList::addPerson(Personne p);
    addPerson est une fonction membre de la classe FriendList.

    Essaie de répondre aux questions suivantes:
    - Quel est le rôle de la classe FriendList? Est-ce:
    1. Manipuler des Personne
    2. Posséder un ensemble de Personne
    3. Les deux

    - Pourquoi est-ce qu'un simple vector<Personne> ne suffit-il pas? Pourquoi dois-tu ajouter une couche (ici avec la classe FriendList)?

    - La question importante: Dans le code ci-dessus (la fonction addPerson), à quel moment le nouvel objet, de type Personne, doit-il être crée? Avant d'appeler cette fonction ou après?

  7. #7
    Membre averti
    Profil pro
    Inscrit en
    Juin 2010
    Messages
    24
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2010
    Messages : 24
    Par défaut
    @r0d : Ce que tu m'écris - je le lis et je le comprends ... enfin je pense
    J'aurais mieux fait d'ajouter un vector<Personne> dans ma classe Personne. Merci pour les remarques, car seul ... je me serai tourné vers des solutions encore plus complexe et incompilable.

    @Dalini71 : Effectivement je voulais pouvoir agir sur les objets personnes.
    J'ai suivi modifier mon code en conséquence et ça fonctionne enfin !
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    void FriendList::addPerson(Personne* p);

  8. #8
    Membre expérimenté Avatar de Dalini71
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2008
    Messages
    181
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2008
    Messages : 181
    Par défaut
    Si tu ne veux pas modifier tes objets de type Personne par la suite, tu peux les passer par copie a ton vecteur de cette façon :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    std::vector<Personne> v;
    Personne p1 ("TOTO");
    v.push_back (p1);
    Sinon si tu veux pouvoir agir sur tes objets Personne depuis le vector, du genre
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    v.at (o).set_name ("TITI");
    Alors la oui il vaut mieux passer par des pointeurs:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    std::vector<Personne*> v;
    Personne* p1 = new Personne ("TOTO");
    v.push_back (p1);
    Par contre l'utilité d'un vector de pointeurs de pointeurs sur Personne, j'avoue que j'ai pas pigé dans ton cas.

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

Discussions similaires

  1. Réponses: 10
    Dernier message: 19/08/2009, 12h02
  2. Réponses: 9
    Dernier message: 27/05/2009, 10h20
  3. Problème sur Array list contenant des objets
    Par patrice cognet dans le forum C#
    Réponses: 3
    Dernier message: 09/11/2008, 18h13
  4. Zoom sur une image contenant des liens hypertexte
    Par Eric C dans le forum Powerpoint
    Réponses: 6
    Dernier message: 26/04/2008, 09h53

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