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 :

affecté une référence à un pointeur, c'est possible ?


Sujet :

C++

  1. #1
    Membre habitué Avatar de bringer
    Homme Profil pro
    Enseignant
    Inscrit en
    Juin 2009
    Messages
    122
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loir et Cher (Centre)

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Bâtiment

    Informations forums :
    Inscription : Juin 2009
    Messages : 122
    Points : 137
    Points
    137
    Par défaut affecté une référence à un pointeur, c'est possible ?
    bonjour,

    je souhaite implémenté le design pattern stratégie en C++. Jusque là tout se passe bien.
    Pour mon exemple, je prend le cas d'un guerrier (dérivé de la classe abstraite Personnages) qui utilise des armes (epee, hache, petite cuillère ...) dérivées de la classe abstraite Armes.

    voici Personnage.hpp :
    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 Personnages{
            public:
                Personnages(const std::string&);
                virtual ~Personnages();
                virtual void attaquer() {}
                void setArme(armes::Armes*);
                void setArme(armes::Armes&);
                void getArme();
                std::string getNom() {return nom;}
     
            private:
                std::string nom;
                armes::Armes* arme;
        };
    ensuite, un morceau de Personnage.cpp
    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
     Personnages::Personnages(const string& n) :nom(n), arme(0)
        {
            cout << "**** constructeur de personnage "<< nom << " ****\n";
        }
     
    Personnages::~Personnages()
        {
            cout << "**** destructeur de Personnage " << nom << " ****\n";
            if (arme)
                delete arme;
        }
     
        void Personnages::setArme(armes::Armes* new_arme)
        {
            if (arme)
                delete arme;
            arme = new_arme;
        }
     
        void Personnages::setArme(armes::Armes& new_arme)
        {
            setArme(&new_arme);
        }
    puis enfin 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
     
        personnages::Guerrier g1("Minator");
        g1.setArme(new armes::Hache(25));
        g1.attaquer();
        // ok ça marche sans problème
        // si je fais
        armes::Hache* hache = new armes::Hache(14);
        g1.setArme(hache);
        // pas de problème là non plus
     
        // mais dans ce cas ....
        armes::Epee epee(13);
        g1.setArme(epee);
        g1.attaquer();
    Dans ce cas, le code fonctionne et me donne les bonnes informations, mais j'ai le droit
    à un joli <<erreur de segmentation>> dans mon destructeur de Personnages
    J'ai essayé plusieurs idées pour palier au problème, sans succès.
    J'avais pensé qu'il fallait 2 variables distinctes du style p_arme* et r_arme&, mais cela semble illogique et de toute façon, ensuite comment attaquer() sait se qu'il doit prendre en compte.
    Cela doit pourtant bien être possible.

    d'avance merci.

  2. #2
    Expert éminent

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Points : 6 911
    Points
    6 911
    Par défaut
    Le destructeur de Personnages fait un delete de arme, mais c'est un pointeur vers une variable automatique, qui a deja ete detruite quand on rentre dans le destructeur de Personnages.
    Les MP ne sont pas là pour les questions techniques, les forums sont là pour ça.

  3. #3
    Membre habitué Avatar de bringer
    Homme Profil pro
    Enseignant
    Inscrit en
    Juin 2009
    Messages
    122
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loir et Cher (Centre)

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Bâtiment

    Informations forums :
    Inscription : Juin 2009
    Messages : 122
    Points : 137
    Points
    137
    Par défaut
    merci de cette réponse aussi rapide,

    mais serait-il possible de préciser un peu la réponse.
    Lorsque j'affecte une nouvelle arme sous la forme new armes::Epee(12) par exemple, il faut bien détruire cette affectation à un moment donné non ?

    Bref, c'est pas très clair pour moi.

  4. #4
    Membre éprouvé

    Profil pro
    Inscrit en
    Décembre 2008
    Messages
    533
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2008
    Messages : 533
    Points : 1 086
    Points
    1 086
    Par défaut
    Dans ton code tu supposes que les objets Armes passés à ton Personnage sont alloués dynamiquement (via new armes::Hache(14);) puisque celui-ci a la charge de les détruire via delete.
    C'est donc une erreur de lui passer un objet alloué statiquement ( armes::Epee epee(13)) sur lequel l'appel d'un delete n'a pas de sens, et se traduit apparemment par un SEGFAULT.

  5. #5
    Membre habitué Avatar de bringer
    Homme Profil pro
    Enseignant
    Inscrit en
    Juin 2009
    Messages
    122
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loir et Cher (Centre)

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Bâtiment

    Informations forums :
    Inscription : Juin 2009
    Messages : 122
    Points : 137
    Points
    137
    Par défaut
    merci cob59, c'est très clair.

    alors, dans ce cas, imaginons que ce soit un code pour un client, comment devrait-il savoir que ce type d'affectation est illégal et comment s'en protéger ?
    Avec une exception type runtimeError ?

    Evidemment, si je supprime la définition de setArme(armes::Armes&), du coup, ça ne compile pas tout simplement !

  6. #6
    Expert éminent

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Points : 6 911
    Points
    6 911
    Par défaut
    Normalement on analyse comment on veut gérer les durées de vies (p.e. soit les personnages sont toujours responsables de détruire les armes, soit ils ne le sont jamais, l’être parfois est rarement indiqué), et on s'aide de pointeurs intelligents a la fois pour communiquer l'intention et pour faciliter l’implémentation.
    Les MP ne sont pas là pour les questions techniques, les forums sont là pour ça.

  7. #7
    Membre éprouvé

    Profil pro
    Inscrit en
    Décembre 2008
    Messages
    533
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2008
    Messages : 533
    Points : 1 086
    Points
    1 086
    Par défaut
    La moins mauvaise solution pourrait être d'utiliser un pointeur intelligent, ce qui solutionnerait les problèmes d'«appartenance» d'un objet Armes :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    class Personnage {
    ...
    private:
      std::shared_ptr<Armes> arme;
    };
     
        void Personnages::setArme(std::shared_ptr<Armes> new_arme)
        {
            arme = new_arme;
        }
    --

    [EDIT] Hop hop, excès de vitesse monsieur Bourguet !

  8. #8
    Membre habitué Avatar de bringer
    Homme Profil pro
    Enseignant
    Inscrit en
    Juin 2009
    Messages
    122
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loir et Cher (Centre)

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Bâtiment

    Informations forums :
    Inscription : Juin 2009
    Messages : 122
    Points : 137
    Points
    137
    Par défaut
    merci à vous deux pour vos réponses éclairantes.

    Je n'ai encore jamais utiliser les pointeurs intelligents, car je m'efforce de comprendre au mieux les pointeurs "stupides"

    J'ai lu aussi une fois un article sur developpez.net (mais je ne sais plus où) qui expliquait que les pointeurs intelligents n'étaient pas toujours la solution la mieux adaptée et qu'il fallait les utiliser avec discernement (surtout ceux de la std)

    Il faudra peut-être se pencher sur la question quand même.
    encore merci

  9. #9
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Points : 13 017
    Points
    13 017
    Par défaut
    Salut,

    Citation Envoyé par bringer Voir le message
    Je n'ai encore jamais utiliser les pointeurs intelligents, car je m'efforce de comprendre au mieux les pointeurs "stupides"
    J'aurais eu tendance à préconiser le contraire. D'abord apprendre à bien utiliser les smart pointer. Ensuite, quand on avance dans l'apprentissage du langage C++, on comprend les services qu'ils peuvent rendre. Et c'est seulement à ce moment que cela peut être formateur de regarder sous le capot les pointeurs nus (plutôt que 'stupides').

    Citation Envoyé par bringer Voir le message
    J'ai lu aussi une fois un article sur developpez.net (mais je ne sais plus où) qui expliquait que les pointeurs intelligents n'étaient pas toujours la solution la mieux adaptée et qu'il fallait les utiliser avec discernement (surtout ceux de la std)
    Je suis surpris. La seule réserve concerne les 'vieux' auto_ptr. Tous ceux de C++11 peuvent être utilisés les yeux fermés.

    Citation Envoyé par bringer Voir le message
    Il faudra peut-être se pencher sur la question quand même.
    Les pointeurs intelligents par Loïc Joly

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

Discussions similaires

  1. Piloter une caméra avec Applescript, c'est possible ?
    Par septembr1 dans le forum AppleScript
    Réponses: 2
    Dernier message: 03/11/2008, 23h35
  2. Une clé secondaire null, c'est possible ?
    Par rad_hass dans le forum MS SQL Server
    Réponses: 2
    Dernier message: 28/10/2008, 13h39
  3. Activer automatiquement une référence si elle n'est pas activée?
    Par drthodt dans le forum Macros et VBA Excel
    Réponses: 4
    Dernier message: 29/10/2007, 17h27
  4. passer une fonction en argument, c'est possible ?
    Par kamouminator dans le forum C
    Réponses: 4
    Dernier message: 10/11/2006, 21h13
  5. Réponses: 3
    Dernier message: 18/07/2006, 10h17

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