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 :

Tableau de pointeurs


Sujet :

C++

  1. #1
    Futur Membre du Club
    Homme Profil pro
    Consultant en sécurité
    Inscrit en
    Juillet 2015
    Messages
    11
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Consultant en sécurité

    Informations forums :
    Inscription : Juillet 2015
    Messages : 11
    Points : 6
    Points
    6
    Par défaut Tableau de pointeurs
    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
    #include <iostream>
    #include <vector>
     
    using namespace std;
     
     
     
                                                // Création des classes
    class Vehicules
    {
    public:
        Vehicules(int prix, int annee) : m_prix(prix), m_anneeConstruction(annee){cout << "Constructeur de vehicule...\n";}
        virtual ~Vehicules() {cout << "Destructeur de vehicule...\n";}
        virtual void afficher();
        virtual void addVehicule();
     
    protected:
        int m_prix;
        int m_anneeConstruction;
        vector<Vehicules*>ListeVehicules;
    };
                                                // Implémentation des fonctions
    void Vehicules::afficher()
        {
            cout <<"Ceci est un vehicule coutant " << m_prix << " euros et fabrique en " << m_anneeConstruction << endl;
        }
     
    void Vehicules::addVehicule()
        {
            ListeVehicules.push_back(new Vehicules(*this));
            ListeVehicules[0]->afficher();
            delete ListeVehicules[0];
        }
     
     
    int main()
    {
     
        Vehicules monVehicule0(10000,2008);
        Vehicules monVehicule1(15000,2010);
        Vehicules monVehicule2(20000,2011);
        monVehicule0.addVehicule();
        monVehicule1.addVehicule();
        monVehicule2.addVehicule();
     
        return 0;
    }
    Je suis bien entendu débutant, le code que j’ai indiqué ci-dessus compile et fonctionne, mais pas comme on pourrait s’y attendre, enfin comme moi je m’y attendais.
    Dans la fonction addVehicule() j’utilise un tableau de pointeurs, membre de la classe Vehicules, ensuite je place une instruction d’affichage en appelant la fonction afficher(), je m’attend donc à obtenir l’affichage de la ligne correspondant à ListeVehicule[0], et finalement j’obtiens l’affichage de tous les objets pointés par le tableau, soit ListeVehicule[0], ListeVehicule[1] et ListeVehicule[2]. Et effectivement il y a bien trois va et vient entre les 2 fonctions, c’est normal me direz-vous il y a 3 appels du main(), ok, mais l’indice du tableau lui reste sur 0, il n’y a aucune boucle d’incrémentation ?
    Ma question : qui incrémente l’indice du tableau ? Le Compilo… ?
    Et est-ce que mon instruction delete Liste Vehicule[0] fonctionnera t-elle correctement , il semblerait bien que oui, car le destructeur est appelé à chaque passage dans la fonction.
    Je vous remercie déjà pour le temps que vous voudrez bien m’accorder à me m’éclairer.

  2. #2
    Futur Membre du Club
    Homme Profil pro
    Consultant en sécurité
    Inscrit en
    Juillet 2015
    Messages
    11
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Consultant en sécurité

    Informations forums :
    Inscription : Juillet 2015
    Messages : 11
    Points : 6
    Points
    6
    Par défaut
    En relisant mon texte, je me suis souvenu que vector est un tableau dynamique, finalement est ce que cela ne viendrait pas de là, je vais creuser...
    Ou alors j'écrase à chaque appel la première case du tableau, ce qui voudrait dire que finalement je ne rempli absolument pas ce tableau..

  3. #3
    Expert éminent
    Avatar de Pyramidev
    Homme Profil pro
    Développeur
    Inscrit en
    Avril 2016
    Messages
    1 469
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur

    Informations forums :
    Inscription : Avril 2016
    Messages : 1 469
    Points : 6 102
    Points
    6 102
    Par défaut
    Tu as brûlé des étapes dans l'écriture de ton code.
    La première étape, c'est d'apprendre comment fonctionne chaque ligne de code que tu veux savoir écrire, pas forcément savoir comment le compilateur l'implémente, mais au moins savoir comment ça se comporte. Sans les briques de base, tu ne pourras pas avancer.

    Si on regarde le code de ta fonction Vehicules::addVehicule :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    void Vehicules::addVehicule()
        {
            ListeVehicules.push_back(new Vehicules(*this));
            ListeVehicules[0]->afficher();
            delete ListeVehicules[0];
        }
    L'expression new Vehicules(*this) alloue dans la mémoire dynamique suffisamment d'espace pour contenir un objet de type dynamique Vehicules. Ensuite, elle appelle dessus le constructeur de recopie de Vehicules. Ce dernier crée un objet de type Vehicules qui fait une copie des membres m_prix, m_anneeConstruction et ListeVehicules. Enfin, la valeur de l'expression correspond à l'adresse de ce nouvel objet de type Vehicules.
    Note que si tu appelles Vehicules::addVehicule() depuis une classe dérivée de Vehicules, new Vehicules(*this) ne va pas cloner tout le contenu d'objet courant : cela va créer un objet de type Vehicules qui ne contiendra qu'une copie des membres m_prix, m_anneeConstruction et ListeVehicules de l'objet courant.

    La fonction std::vector<Vehicules*>::push_back ajoute dans le vecteur un pointeur de type Vehicules*, c'est à dire une adresse. Note que ce vecteur ne fait que stocker l'adresse. Il ne sait pas si ce pointeur pointe vers un objet de type dynamique Vehicules ou qui dérive de Vehicules. Il ne sait pas non plus si l'objet pointé est stocké dans la pile ou la mémoire dynamique. Il ne fait pas de copie de l'objet pointé. Il ne fait que stocker l'adresse.

    ListeVehicules[0]->afficher() prend le pointeur qui se trouve à la position 0 dans le vecteur et appelle la fonction afficher. Comme cette fonction est virtuelle, la fonction appelée dépend du type dynamique de l'objet pointé. Si c'est un objet de type Vehicules, cela appellera Vehicules::afficher. Si c'est un objet de type ClasseQuiDeriveDeVehicules qui redéfinit une fonction afficher, cela appellera ClasseQuiDeriveDeVehicules::afficher.

    delete ListeVehicules[0] prend le pointeur qui se trouve à la position 0 et fait un delete dessus. Comme le destructeur de Vehicules est virtuel, le destructeur appelé dépend du type dynamique de l'objet pointé. Après l'appel au destructeur, l'espace mémoire sur lequel le constructeur de l'objet avait été appelé est désalloué.
    Note que le vecteur ne sait absolument pas ce que tu as fait avec ce pointeur. Il ne va pas décider de lui-même de retirer le pointeur. Il ne fera rien. A la position 0 de ton vecteur, tu as désormais un pointeur vers une zone mémoire invalide.

    Étant donné le code de ta fonction Vehicules::addVehicule, si tu l'appelles plusieurs fois de suite sur le même objet, la 2e fois, ça donne ça :
    ListeVehicules.push_back(new Vehicules(*this)) crée un objet et ajoute son adresse dans le vecteur à la position 1, car la position 0 est déjà occupée.
    ListeVehicules[0]->afficher() prend le pointeur à la position 0 qui pointe vers un objet qui n'existe plus et essaie d'appeler afficher. Le comportement est indéterminé => crash probable du programme.
    delete ListeVehicules[0] prend le pointeur qui se trouve à la position 0 qui pointe vers un objet qui n'existe plus et fait un delete dessus => crash probable du programme.

    A part ça, dans ton code, chacun de tes objets monVehicule0, monVehicule1 et monVehicule2 contient sa propre liste de véhicules. Ce n'est pas une liste commune car ListeVehicules est une variable membre non statique, comme m_prix et m_anneeConstruction.

    Dans un premier temps, relis attentivement ton cours de C++.
    Ensuite, refais la conception. Un objet qui est à la fois un véhicule et un ensemble de véhicules, ça n'a pas de sens.
    Après, écris ton code.
    Enfin, si tu veux, publie une nouvelle version de ton code ici. S'il y a des problèmes de conception, il y aura sûrement au moins un d'entre nous pour les signaler.

  4. #4
    Futur Membre du Club
    Homme Profil pro
    Consultant en sécurité
    Inscrit en
    Juillet 2015
    Messages
    11
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Consultant en sécurité

    Informations forums :
    Inscription : Juillet 2015
    Messages : 11
    Points : 6
    Points
    6
    Par défaut
    Merci à toi Pyramidev pour cette réponse détaillée et claire, je vais plancher sur mon code, mais je suis content déjà de m'apercevoir que tes explications ne m'ont pas du tout parus obscures. Depuis que j'étudie en solo ce language, je dois bien avouer qu'il est le plus difficile que j'ai étudié jusqu'à présent, cette difficulté est probablement proportionnelle à sa puissance. Cela fait maintenant 1 an que je l'étudie et j'ai encore l'impression de balbutier. J'ai étudié l'assembleur, le visual basic, et cela m'a pris beaucoups moins de temps pour me débrouiller dans la création de programmes bureautiques opérationnels. Enfin je continue, encore merci à toi pour le temps consacrer à me répondre. A++

  5. #5
    Membre éclairé
    Homme Profil pro
    Chercheur en informatique
    Inscrit en
    Juin 2008
    Messages
    522
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Chercheur en informatique

    Informations forums :
    Inscription : Juin 2008
    Messages : 522
    Points : 725
    Points
    725
    Par défaut
    Salut à toi DATA13,
    Je me permets de te conseiller comme tu as l'air d'être un débutant, d'éviter les pointeurs dans un premier temps. Moins il y aura de pointeurs dans ton code, et mieux il se portera (il est si vite fait d'oublier de supprimer un objet ou d'appeler une fonction sur un objet détruit). D'ailleurs pourquoi as tu voulu faire un tableau de pointeur au lieu d'un tableau tout court ?
    Si ton but est d'apprendre les pointeurs, je te conseille de coder une liste chainée.
    Dernière chose, si ton problème est résolu, utilise le bouton correspondant.
    Cordialement
    Raphchar.

  6. #6
    Futur Membre du Club
    Homme Profil pro
    Consultant en sécurité
    Inscrit en
    Juillet 2015
    Messages
    11
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Consultant en sécurité

    Informations forums :
    Inscription : Juillet 2015
    Messages : 11
    Points : 6
    Points
    6
    Par défaut
    Bonjour raphchar,
    Merci pour ta réponse et tes conseils, comme je le disais précédemment, j'étudie ce language solo, les pointeurs ne me perturbent pas trop le cas échéant je pourrais utiliser les smart pointers, mais le but de l'exercice ici était de placer un vecteur dans une classe: pour résumer :
    1 classe de base Vehicules,
    2 classes dérivées de Vehicules, Voitures et Moto

    Et alors j'aurais voulu ajouter une classe ParkVehicules, avec en attribut un vecteur listeVehicules. Mais voilà, comme je n'arrive pas à l'intégrer dans l'héritage car il n'y a pas la fameuse liaison "est un" entre ParkVehicules et les autres classes
    en effet 1 ParkVehicule n'est pas un véhicule,ni une voiture, ni une moto. Et l'inverse ne fonctionne pas non plus, il faudrait alors que cette classe ne soit pas dans la branche d'héritage, mais alors quid des liaisons ?? Voilà, voilà, mais je trouverai la solution, je trouve toujours une solution, c'était surtout pour gagner du temps que je poste sur ce site, et je constate qu'il y a quelques sérieuses pointures dans le domaine et je ne voudrais paraître totalement idiot. J' ai d'ailleur déjà une solution que je dois encore optimaliser mais qui fonctionne (code à débroussailler ci-dessous), MAIS c'est pas ce que je voulais faire, alors je continue de chercher.
    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
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    #include <iostream>
    #include <vector>
     
    using namespace std;
     
                                                // Création des classes
    class Vehicules
    {
    public:
        Vehicules(int prix, int annee); // constructeur avec 2 paramètres : int prix et un int année
        virtual void afficher() const=0; //Fonction virtuelle pure à redéfinir dans les classes dérivées -> classe abstraite
                                                        // plus possible d'instancier un objet de cette classe
        virtual ~Vehicules(); // destructeur de véhicule virtuelle par ce que il y a une fonction virtuelle dans la classe
    protected:
        int m_prix;
        int m_anneeConstruction;
     
    };
     
     
    class Voitures : public Vehicules
    {
    public:
        Voitures(int prix, int annee, int portes);//constructeur avec 3 paramètres int :  prix, année et portes
        virtual void afficher() const;
        virtual ~Voitures(); // Destructeur de voitures
        void roue() const;
    private:
        int m_portes;
     
    };
     
    class Moto : public Vehicules
    {
    public:
        Moto(int prix, int annee, double vitesseMax);//constructeur avec 2 paramètres int et un 1 paramètre double : prix, année et vitesseMax
        virtual void afficher() const;
        virtual ~Moto();
        void roue() const;
    private:
        double m_vitesse;
     
    };
     
    class Camion : public Vehicules
    {
    public:
        Camion(int prix, int annee, double poidsNet);
        virtual void afficher() const;
        virtual~Camion();
        void roue() const;
    private:
        double m_poids;
    };
     
     
     
                                        //Implémentation des constructeurs
     
    Vehicules::Vehicules(int prix, int annee) : m_prix(prix), m_anneeConstruction(annee) {}
     
    Voitures::Voitures(int prix, int annee, int portes) : Vehicules(prix, annee) , m_portes(portes) {}
     
    Moto::Moto(int prix, int annee, double vitesseMax) : Vehicules(prix, annee) , m_vitesse(vitesseMax) {}
     
    Camion::Camion(int prix, int annee, double poidsNet) : Vehicules(prix, annee), m_poids(poidsNet) {}
     
                                        // Implémentation des fonctions
     
    void Vehicules::afficher() const
    {
        cout <<"Ceci est un vehicule coutant " << m_prix << " euros et fabrique en " << m_anneeConstruction << endl;
     
    }
     
    void Voitures::afficher() const
    {
        cout << "Ceci est une voiture avec " << m_portes << " portes et coutant " << m_prix << " euros et fabrique en " << m_anneeConstruction << endl;
     
    }
     
    void Voitures::roue() const
    {
        cout << " le nombre de roues est 4" << endl;
    }
     
    Voitures addVoiture() //fonction hors classe entrée voiture
    {
        int a,b,c;
        cout << "Prix du vehicule : ";
        cin >> a;
        cout << "Annee de fabrication du vehicule : ";
        cin >> b;
        cout << "Nombre de portes : ";
        cin >> c;
     
    Voitures maVoiture(a,b,c); // Appelle le constructeur de voiture
    return maVoiture;
    }
    void Moto ::afficher() const
    {
        cout << "Ceci est une moto allant a " << m_vitesse << " km/h  et coutant " << m_prix << " euros et fabrique en " << m_anneeConstruction << endl;
     
    }
     
    void Moto::roue() const
    {
        cout << " le nombre de roues est 2" << endl;
    }
     
    Moto addMoto() //Fonction hors classe entrée moto
    {
        int a,b;
        double c;
        cout << "Prix de la moto: ";
        cin >> a;
        cout << "Annee de fabrication du vehicule : ";
        cin >> b;
        cout << "Vitesse maxi de la moto : ";
        cin >> c;
    Moto maMoto(a,b,c);
    return maMoto;
    }
    void Camion::afficher() const
    {
        cout << "Ceci est un camion pouvant transporter " << m_poids << "kg et coutant " << m_prix << " euros et fabrique en " << m_anneeConstruction << endl;
     
    }
     
    void Camion::roue() const
    {
        cout << " le nombre de roues est 8" << endl;
    }
     
    Camion addCamion() // fonction hors classe entrée camion
    {
         int a,b;
        double c;
        cout << "Prix du camion: ";
        cin >> a;
        cout << "Annee de fabrication du vehicule : ";
        cin >> b;
        cout << "Poids net de chargement : ";
        cin >> c;
    Camion monCamion(a,b,c);
    return monCamion;
    }
     
                                        // Implémentation des destructeurs
     
    Vehicules::~Vehicules() {}
     
    Voitures::~Voitures() {}
     
    Moto::~Moto() {}
     
    Camion::~Camion() {}
     
     
     
     
    int main()
    {
                                    // déclaration des variables
     
    vector <Vehicules*> listeVehicules; // vecteur de pointeurs sur vehicules
    int i;
    bool fQuit = false;
    int choix;
     
     
    while(fQuit==false)
    {
        cout << "Entree de nouveaux vehicules faite votre choix\n";
        cout << " (1)Entrez une voiture \n (2)Entrez une moto\n (3)Entrez un camion\n (4)Quittez\n Votre choix : " ;
        cin >> choix;
     
        switch(choix)
        {
            case 1 : listeVehicules.push_back(new Voitures(addVoiture()));
            break;
            case 2 : listeVehicules.push_back(new Moto(addMoto()));
            break;
            case 3 : listeVehicules.push_back(new Camion(addCamion()));
            break;
            default : fQuit = true;
            break;
        }
    }
            cout << "Desirez vous voir la liste des vehicules en stock :";
            cout << "(1)Oui  (2)Non : ";
            cin >> choix;
            if(choix == 1)
            {
                cout << "Num                   Caracteristiques du vehicule \n";
                for(i=0; i<listeVehicules.size(); i++){
                   cout << i << "       "; listeVehicules[i]->afficher();}
     
                for(i=0; i<listeVehicules.size(); i++){
                    delete listeVehicules[i];
                    listeVehicules[i] = nullptr;}
            }
            else
     
    return 0;
    }

  7. #7
    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 : 49
    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
    Points : 16 213
    Points
    16 213
    Par défaut
    Citation Envoyé par DATA13 Voir le message
    Et alors j'aurais voulu ajouter une classe ParkVehicules, avec en attribut un vecteur listeVehicules. Mais voilà, comme je n'arrive pas à l'intégrer dans l'héritage car il n'y a pas la fameuse liaison "est un" entre ParkVehicules et les autres classes
    en effet 1 ParkVehicule n'est pas un véhicule,ni une voiture, ni une moto. Et l'inverse ne fonctionne pas non plus, il faudrait alors que cette classe ne soit pas dans la branche d'héritage,
    Jusque là, je suis d'accord avec toi
    Citation Envoyé par DATA13 Voir le message
    mais alors quid des liaisons ??
    Mais là, je ne comprends plus ce que tu dis
    Citation Envoyé par DATA13 Voir le message
    Voilà, voilà, mais je trouverai la solution, je trouve toujours une solution, c'était surtout pour gagner du temps que je poste sur ce site, et je constate qu'il y a quelques sérieuses pointures dans le domaine et je ne voudrais paraître totalement idiot. J' ai d'ailleur déjà une solution que je dois encore optimaliser mais qui fonctionne (code à débroussailler ci-dessous), MAIS c'est pas ce que je voulais faire, alors je continue de chercher.
    Pourquoi ta classe Vehicles a-t-elle un nom au pluriel ? Elle représente 1 véhicule, d'ailleurs, pour les classes dérivées, tu as utilisé le singulier. Ça a l'air d'un détail, mais c'est important.

    Sinon, tu es conscient d'avoir une fuite mémoire dans ton code ? Tu as l'air de connaître les pointeurs intelligents, pourquoi ne les utilises-tu pas ?
    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.

  8. #8
    Expert éminent
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Décembre 2015
    Messages
    1 565
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Décembre 2015
    Messages : 1 565
    Points : 7 642
    Points
    7 642
    Par défaut
    Bonjour,

    On doit distinguer l'utilisation de pointeurs, et la problématique de l'allocation dynamique. Les cas d'utilisation des pointeurs peuvent être :
    1. Le pointeur désigne un objet identifié, il peut être efficacement remplacé par une référence ou un reference_wrapper
    2. Le pointeur désigne un objet alloué dynamiquement, là se pose le problème de qui/quand libérer cet objet;
    3. Le pointeur désigne rien ou un objet ou peut changer d'objet. On peut peut-être garder un pointeur.
    Dans le cas (b), l'utilisation de pointeurs intelligents est de loin la manière le plus sûre. Il faut alors n'utiliser que ces pointeurs pour désigner l'objet. Il n'empêche que le problème de la responsabilité doit être compris pour le développeur, le pointeur intelligent est en réalité bête et discipliné; il doit être utilisé intelligemment.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    class Toto;
    Toto* ptrToto = 0;        // peut désigner un objet ou rien (alloué sur la pile, global,
                              // dans un objet, mais dynamique ou tls à éviter)
    std::unique_ptr<Toto>;    // désigne un objet dynamique, il en sera le seul responsable
    std::shared_ptr<Toto>;    // désigne un objet dynamique, d'autre partageront le responsabilité
    Toto& refToto = *ptrToto; // désigne un objet
    std::vector<Toto>;        // désigne des objets, si on se limite à un seul on a un équivalent à l'unique_ptr qui est
                              // peut-être plus facile à comprendre quand on débute. Mais ne peut pas gérer l'héritage!
     
    // Pour avoir une table de Toto et qui peut aussi gérer des classes dérivant de Toto
    std::vector<Toto*>;       // n'effraie pas les débutants, pourtant il est source d'erreurs et d'incompréhensions.
    std::vector<std::unique_ptr<Toto>>; // pour des objets dynamiques, le vector est le responsable (enlever un élément le détruit)
    std::vector<std::reference_wrapper<Toto>>; // pour des objets dont on n'a pas la responsabilité
    std::deque<std::shared_ptr<Toto>>; // Le plus simple quand on débute, souple aux modifications et au partage de responsabilité en restant peu consommateur.
    Pour gérer des véhicules, on peut mettre la responsabilité dans une table, le park lui pourra être constitué d'une table dont les éléments désignent ces véhicules.
    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
    std::deque<std::shared_ptr<Vehicule>> gListeDesVehicules;
    struct Park {
       std::deque<std::weak_ptr<Vehicule>>  liste;
       // Utiliser un weak_ptr permet : Si un véhicule disparaît, il disparaît instantanément du Park
       // Utiliser un shared_ptr permettrait : Si un véhicule est ôté de la liste globale, il reste vivant tant qu'il est dans un Park.
       void add( std::shared_ptr<Vehicule> v ) { liste.push_back( v ); }
       void lesAfficher()const {
          for ( auto const& v : liste ) {
             if ( std::shared_ptr<Vehicule> pv = v.lock() ) { // accès au shptr
                  pv->afficher();
             }// sinon le véhicule n'existe plus, il faudra le purger
          }
       }
    };
    std::shared_ptr<Vehicule> v = std::make_shared<Moto>( /*paramètres du constructeur de Moto*/ );
    gListeDesVehicules.push_back( v );
    park.add( v );
    v = std::make_shared<Voiture>( /*paramètres du constructeur de Voiture*/ );
    gListeDesVehicules.push_back( v );
    park.add( v );
     
    gListeDesVehicules.erase( gListeDesVehicules.begin() );  // supprime 'proprement' la Moto
    park.lesAfficher();                                      // il n'y a plus que la voiture dans le park

  9. #9
    Futur Membre du Club
    Homme Profil pro
    Consultant en sécurité
    Inscrit en
    Juillet 2015
    Messages
    11
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Consultant en sécurité

    Informations forums :
    Inscription : Juillet 2015
    Messages : 11
    Points : 6
    Points
    6
    Par défaut
    Citation Envoyé par JolyLoic Voir le message
    Sinon, tu es conscient d'avoir une fuite mémoire dans ton code ? Tu as l'air de connaître les pointeurs intelligents, pourquoi ne les utilises-tu pas ?
    Tout d'abord merci pour ta réponse. Et non je ne suis pas conscient d'une fuite dans ce code, il y a un boucle for qui désalloue les espaces mémoires et fait pointer les pointeurs sur NULL, je vérifie quand même que cette boucle est appelée dans tous les cas de figure. Pour le reste, oui le pluriel n'est là que parce que Vehicules peut être plusieurs objets(voiture, moto, camion), mais 1 à la fois.

    Merci encore et A+

    Oui effectivement, quand la reponse est négative il manque le code dans le else de la boucle if pour la répétition de la désallocation des espaces mémoires, oups!!

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

Discussions similaires

  1. Tableau de pointeur de fonction
    Par Gryzzly dans le forum C
    Réponses: 7
    Dernier message: 31/12/2005, 10h47
  2. Tableau de pointeurs sur objets
    Par bassim dans le forum C++
    Réponses: 11
    Dernier message: 13/12/2005, 19h45
  3. [GCC] Tableau de pointeurs pour accès multiples en asm
    Par Flo. dans le forum x86 32-bits / 64-bits
    Réponses: 2
    Dernier message: 12/12/2005, 08h47
  4. tableau de pointeurs
    Par seal3 dans le forum C++
    Réponses: 7
    Dernier message: 01/11/2005, 20h51
  5. Tableau de pointeurs de fonctions
    Par Alp dans le forum C++
    Réponses: 7
    Dernier message: 29/10/2005, 13h19

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