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 :

Passage d'un pointeur en parametre


Sujet :

C++

  1. #1
    Membre confirmé

    Profil pro
    Inscrit en
    Avril 2005
    Messages
    162
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2005
    Messages : 162
    Points : 545
    Points
    545
    Par défaut Passage d'un pointeur en parametre
    Voila, j'ai une classe du type :

    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
     
     
    class Widget
    {
      public:
        Widget() : s_(0) {}
        ~Widget() {  delete s_; s_ = 0; }  
     
        void execute()
        {
          s_.apply();
        }
     
        void setStrategy(Strategy* s)
        {
          if (s_ != 0)
            delete s_;
          s_ = s;
        }
     
      private:
       Strategy* s_;
    }

    Voila, rien d'extraordinaire jusque la , mais supposons, qu'au lieu de faire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    widget.setStrategy(new Strategy)
    Je fasse :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    widget.setStrategy(&Strategy())
    Dans ce derner cas, la classe Widget appelera un delete sur un objet alloue sur la pile ....
    Donc, je voulais savoir comment s'en sortir dans ce cas ?
    Je sais qu'on pourrait surcharger et encapsuler en private ::operator new pour eviter de faire un new Strategy et supprimer le delete dans la classe Widget, mais existe - t - il d'autres moyens ?

  2. #2
    Rédacteur

    Avatar de Davidbrcz
    Homme Profil pro
    Ing Supaéro - Doctorant ONERA
    Inscrit en
    Juin 2006
    Messages
    2 307
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : Suisse

    Informations professionnelles :
    Activité : Ing Supaéro - Doctorant ONERA

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 307
    Points : 4 732
    Points
    4 732
    Par défaut
    Déjà dans ton 2eme cas ton compilo devrait t'avertir que tu prend l'adresse d'un objet temporaire qui ne sera plus valide dès la fin de l'instruction.

    Pour éviter ce genre de problème, on pourrait dans setStrategy effectuer une copie de la stratégie via Prototypage (cela revient à dire que le widget est le gestionaire de la stratégie) . Par contre on à une gaspile de mémoire si on continue à passer l'objet en paramètre via pointeur car on ne sait pas comment il à été alloué. Pour éviter cela, il faudrat le passer en référénce constante puis le cloner.

    Ca donnerai un truc du genre :

    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
     
    class Widget
    {
      public:
        Widget() : s_(0) {}
        ~Widget() {  delete s_; s_ = 0; }  
     
        void execute()
        {
          s_.apply();
        }
     
        void setStrategy(const Strategy& s)
        {
          s_ = s.Clone();
        }
     
      private:
       Strategy* s_;
    }
    Et quelque chose comme :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    widget.setStrategy(Strategy())
    passerai sans problème.

    EDIT: code non testé.
    "Never use brute force in fighting an exponential." (Andrei Alexandrescu)

    Mes articles dont Conseils divers sur le C++
    Une très bonne doc sur le C++ (en) Why linux is better (fr)

  3. #3
    Membre confirmé

    Profil pro
    Inscrit en
    Avril 2005
    Messages
    162
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2005
    Messages : 162
    Points : 545
    Points
    545
    Par défaut
    oui, en effet setStrategy(&Strategy()) genererait un warning,

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    Strategy s;
    setStrategy(&s)
    aurait deja ete plus logique.

    Et sinon, plutot que de faire un clonage qui provoque une construction supplementaire, que penserait tu d'encapsuler la creation du ptr Strategy* dans un auto_ptr et de n'utiliser que ce auto_ptr dans la classe Widget ?

    on aurait dans Widget :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    setStrategy(auto_ptr<Strategy> s) {...}

  4. #4
    Membre éprouvé
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    1 064
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2005
    Messages : 1 064
    Points : 1 053
    Points
    1 053
    Par défaut
    Ton problème est que tu as une entité (ici un objet) qui veut gérer le cycle de vie d'un objet construit par une autre entité (dans ton exemple la pile, mais ça pourrait aussi bien être un autre objet) mais ta syntaxe n'oblige pas à déléguer la gestion de ce cycle de vie.

    L'utilisation du clonage est une façon de contourner ce problème, mais ce n'est pas ce que tu voulais faire au départ.

    Donc je te conseillerais exactement la même chose que vandamme. L'auto_ptr est très utile dans ce genre de cas, en passer un par valeur à une fonction enlève toute possibilité pour l'entité appelante de conserver la gestion du cycle de vie de l'objet, bref exactement ce dont tu as besoin.

Discussions similaires

  1. Passage de pointeur en parametre
    Par cout dans le forum C
    Réponses: 3
    Dernier message: 14/06/2006, 16h45
  2. Réponses: 5
    Dernier message: 21/11/2005, 01h40
  3. passage d'un tableau en parametre d'une fonction
    Par ataya dans le forum C++Builder
    Réponses: 10
    Dernier message: 26/10/2005, 13h30
  4. [POO] passage nom objet dsn les parametres d'une fonction
    Par melou dans le forum Général JavaScript
    Réponses: 12
    Dernier message: 21/10/2005, 17h26
  5. passage d'une variable en parametre
    Par duga dans le forum Langage
    Réponses: 4
    Dernier message: 11/09/2005, 12h19

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