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 :

polymorphisme encore dsl


Sujet :

C++

  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    77
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2006
    Messages : 77
    Par défaut polymorphisme encore dsl
    Bonjour,
    J'appelle dans operator+ une fonction add qui sera défini dans chacun des class héritant de Space.
    Voir le code
    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
     
    class Space
    {
    public:
      Space & operator +=(const Space x);
      virtual inline void add(const  Space *x) ;
    };
    Space & Space::operator +=(const Space x)
    {
      this->add(&x);
    }
    class Space1d:public Space
    {
    public:
      int i;
      Space1d():i(0){}
      Space1d(int j):i(j) {}
      inline void add( const Space* x)
        {
          this->i = x->i;
        }
    };
    Le problème à la compilation est :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    «const class Space» has no member named «i»
    i.e. pour le compilateur l'argument x de add est un oblet de la classe mère Space donc qui n'a pas d'instance int i. Ce que je voudrais savoir c'est comment résoudre ce problème???

    Merci,
    PS: Je remercie les habitués de ce site pour le sujet d'avant

  2. #2
    Membre confirmé
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    77
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2006
    Messages : 77
    Par défaut
    Pour résoudre le problème, je surchage l'opérateur.
    Merci
    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
     
    class Space
    {
    public:
      friend std::ostream& operator << (std::ostream& O, const Space& B);
       Space & operator +=(const Space x);
     
      virtual void Print(std::ostream& O) const
        {
          cout << "toto";
        }
    };
     
    Space & Space::operator +=(const Space x)
    {
      return *this;
    }
    std::ostream& operator << (std::ostream& O, const Space& B)
    {
        B.Print(O);
        return O;
    }
     
    class Space2d:public Space
    {
    public:
      int i[2];
      Space2d()
        {i[0]=0;i[1]=0;}
      Space2d(int i0,int i1){i[0]=i0;i[1]=i1;}
     
       void Print(std::ostream& O) const
        {
         cout << i[0]<<"  "<<i[1]<<endl;
        }
      Space2d & operator +=(const Space2d x)
        {
          i[0]+=x.i[0];
          i[1]+=x.i[1];
        }
    };
    Ca commence à être bien le C++ par rapport à ma religion d'antan le C pure.

  3. #3
    Membre chevronné
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2006
    Messages
    366
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Mai 2006
    Messages : 366
    Par défaut
    En déclarant la variable i comme membre de ta classe Space (public ou protected mais pas private) ...

    Ensuite déclarer un fonction virtual inline ne sert a rien, ta fonction ne sera pas inlinée puisque le virtual indique justement que la fonction peut être redéfinie dans les classes déribvées et qu'il faut donc vérifier ça à l'exécution, lors de l'appel de la fonction, alors que l'inline indique au compilo de remplacer l'appel de la fonction par lae corps de la fonction lors de la compilation.

  4. #4
    Membre confirmé
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    77
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2006
    Messages : 77
    Par défaut
    Big 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
     
    int main()
    {
    Space2d s1,s2(2,3);
      Space *s;
     
     
      s1+=s2;
      cout << s1;
     
      s = &s1;
     
      *s+=s2;
      cout << *s;
    }
    Affichage
    Il a fait l'addition définie pour la class mère Space or j'aurai voulu qu'il fasse celle de Space2d.....

    De plus s2=*s;
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    _rm.cpp:109: erreur: no match for «operator=» in «s2 = * s»
    _rm.cpp:60: note: candidats sont: Space2d& Space2d::operator=(const Space2d&)
    A l'aide!!!!!!!

  5. #5
    Membre chevronné
    Profil pro
    Inscrit en
    Novembre 2003
    Messages
    394
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2003
    Messages : 394
    Par défaut
    Citation Envoyé par bolhrak
    Ensuite déclarer un fonction virtual inline ne sert a rien
    La plupart des compilos supportent ce type de déclaration. Ils garantissent le polymorphisme mais sont capable 'd'inliner' quand le type ne fait pas de doute.
    Ex:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    class Foo { 
    public:
        virtual int bar() { return val_; } 
    private:
      val_;
    }; 
    int main()
    {
      Foo foo;  // Création sur la pile, pas de polymorphisme possible
      int x = foo.bar(); // Pas de liaison dynamique --> inline
    }

  6. #6
    Membre chevronné
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2006
    Messages
    366
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Mai 2006
    Messages : 366
    Par défaut
    Effectivement je n'avais pas pensé à ce cas là ! Généralement quand j'ai une hiérarchie de classe c'est justement pour exploiter le polymorphisme et je déclare donc mes variables sur le tas

  7. #7
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Par défaut
    Ce que tu cherches à faire c'est du double-dispatch, càd que la liaison dynamique ne dépend non plus du type d'une instance, mais de deux. Et là les mécanismes de fonctions virtuelles ne sont plus suffisant.

    Fais quelques recherches sur le sujet.

  8. #8
    Membre confirmé
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    77
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2006
    Messages : 77
    Par défaut
    j'essaye mais je n'y arrive pas...

    snif snif

  9. #9
    Membre confirmé
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    77
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2006
    Messages : 77
    Par défaut
    vraiement personne...

  10. #10
    Invité
    Invité(e)
    Par défaut
    ca suffit le spam... cherche donc, et laisse le temps à ceux qui savent de répondre

  11. #11
    Membre chevronné
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2006
    Messages
    366
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Mai 2006
    Messages : 366

  12. #12
    Invité
    Invité(e)
    Par défaut
    Citation Envoyé par bolhrak
    cf. ma signature

  13. #13
    Membre chevronné
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2006
    Messages
    366
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Mai 2006
    Messages : 366
    Par défaut
    Le proxy de ma boîte me bloque l'accès à ton lien :s

    Je regarderai ce soir :p

  14. #14
    Expert confirmé
    Avatar de Luc Hermitte
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2003
    Messages
    5 287
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Août 2003
    Messages : 5 287
    Par défaut
    Suis-je le seul à être perturber par le mélange entre un héritage et des opérateurs qui ont une gueule furieusement mathématique?
    Tu cherches à modélier quoi ?
    Blog|FAQ C++|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS|Bons livres sur le C++
    Les MP ne sont pas une hotline. Je ne réponds à aucune question technique par le biais de ce média. Et de toutes façons, ma BAL sur dvpz est pleine...

  15. #15
    Membre Expert
    Avatar de Patriarch24
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Septembre 2003
    Messages
    1 047
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Industrie

    Informations forums :
    Inscription : Septembre 2003
    Messages : 1 047
    Par défaut
    Citation Envoyé par Luc Hermitte
    Suis-je le seul à être perturber par le mélange entre un héritage et des opérateurs qui ont une gueule furieusement mathématique?
    Non tu n'es pas le seul . Et je comprends pas vraiment le fait d'"ajouter" des espaces --Space--, possiblement de dimensions différentes, entre eux.

  16. #16
    Membre confirmé
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    77
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2006
    Messages : 77
    Par défaut
    Voilà la solution que je propose à mon 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
    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
     
    #include <iostream>
    #include <vector>
    #include <list>
     
    using namespace std;
     
     
    class Point
    {
    public:
      friend std::ostream& operator << (std::ostream& O, const Point& x);
      virtual Point & operator +=( Point& x)=0;
      virtual Point & operator -=( Point& x)=0;
      virtual void Print( Point& B)=0 ;
    };
     
    std::ostream& operator << (std::ostream& O,  Point& B)
    {
      B.Print(B);
      return O;
    }
    Point & operator+(Point& x1, Point& x2)
    {
      Point & x= x1;
      return x+=x2;
    }
    Point & operator-(Point& x1, Point& x2)
    {
      Point & x= x1;
      return x-=x2;
    }
     
     
    template< class T > class Target
    {
    public :
      virtual T & add( T& x) = 0 ;
      virtual T & sub( T& x) = 0 ;
      virtual void f_Print(T& x)=0;
    } ;
     
     
    template< class T > class F : virtual public Point
    {
    public :
      virtual Point & operator +=( Point& x)
        {
          typedef Target< T > TargetT ;
          return dynamic_cast< TargetT& >(x).add( static_cast< T& >(*this) ) ;
        }
      virtual Point & operator -=( Point& x)
        {
          typedef Target< T > TargetT ;
          return dynamic_cast< TargetT& >(x).sub( static_cast< T& >(*this) ) ;
        }
      virtual void Print( Point& x)
        {
          typedef Target< T > TargetT ;
          return dynamic_cast< TargetT& >(x).f_Print(  static_cast< T& >(*this) ) ;
        }
    };
     
     
    class Point1d : public F< Point1d >,
              public Target< Point1d >
    {
    public :
      int i;
      Point1d()
        {i=0;}
      Point1d(int j){i=j;}
     
       Point1d & add( Point1d& x){this->i+=x.i;}
       Point1d & sub( Point1d& x){this->i-=x.i;}
      virtual void f_Print(Point1d& x)
        {
          cout << i<< endl;
        }
    } ;
     
     
     
    class Point2d : public F< Point2d >,
              public Target< Point2d >
     
    {
    public :
      int i[2];
      Point2d()
        {i[0]=0;i[1]=0;}
      Point2d(int i0,int i1){i[0]=i0;i[1]=i1;}
      Point2d & add( Point2d& x){this->i[0]+=x.i[0];this->i[1]+=x.i[1];}
      Point2d & sub( Point2d& x){this->i[0]-=x.i[0];this->i[1]-=x.i[1];}
      virtual void f_Print( Point2d& x)
        {
          cout << i[0]<< " " << i[1]<< endl;
        }
    };
     
     
     
    int main()
    {
     
      Point1d a(1), c(2) ;
      Point2d b(1,2) ;
     
     
      Point*ptr;
      ptr = &a;
      *ptr = c - *ptr;
      cout << *ptr;
     
    ptr =&b;
     
     
      *ptr+=*ptr;
      cout << *ptr;
     
    }
    Mon affichage console:

    youpi ca marche

  17. #17
    Membre confirmé
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    77
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2006
    Messages : 77
    Par défaut
    Maintenant si ça intéresse des gens, je peux comparer l'efficacité de ce code face au c classique où chaqu'une des fonction est écrites n fois ( n le nombre de type différents).

    Ah oui, je voudrais savoir si le double-dispatch est résolu à la compilation où à l'éxecution. Car si c'est à l'éxécution alors c'est sure que mon code C++ va tourner moins vite

  18. #18
    Membre confirmé
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    77
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2006
    Messages : 77
    Par défaut
    Suis-je le seul à être perturber par le mélange entre un héritage et des opérateurs qui ont une gueule furieusement mathématique?
    Qu-est ce que vous voulez dire par là??

  19. #19
    Expert confirmé

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Par défaut
    Je crois que tu n'as toujours pas repondu a la question de fond soulevee par Luc. Generalement des operations comme l'assignation ou d'addition ont du sens sur des classes ayant une semantique de valeur et les operations virtuelles ont du sens sur des classes ayant une semantique d'entite. Les rares cas ou j'ai vu les deux ensembles, c'etait souvent dans le cadre de l'idiome lettre-enveloppe (qui m'a toujours semble bizarre et auquel je prefere la composition; mais c'est un autre debat).

    Tu cherches donc a faire quelque chose de rarement pertinent, et tu n'es visiblement pas dans l'exception principale ou c'est pertinent.

    Quelques remarques en passant:
    - pourquoi operator<< est-il friend. Si c'est necessaire, c'est generalement un signe que quelque chose ne va pas dans l'interface publique.
    - pourquoi += et -= prennent-il une reference non constante?
    - pourquoi + prend-il des references non constantes?
    - + et - retournent des references (non constantes en plus) vers des variables locales

    La suite est quelque chose de tres bizarre. Quel est le probleme que tu cherches a resoudre?

  20. #20
    Membre émérite
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    780
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Mai 2006
    Messages : 780
    Par défaut
    Citation Envoyé par Jean-Marc.Bourguet
    - pourquoi operator<< est-il friend. Si c'est necessaire, c'est generalement un signe que quelque chose ne va pas dans l'interface publique.
    ça peut se justifier si on doit appeller certaines méthodes non publiques de l'objet dans operator<< mais qu'on ne veut pas du tout qu'elles soient publiques, pour garder l'encapsulation.

    (dans C++ coding standards je crois, "friend ne brise pas l'encapsulation mais la renforce", quelque chose comme ça)

Discussions similaires

  1. Programmer encore en VB 6 c'est pas bien ? Pourquoi ?
    Par Nektanebos dans le forum Débats sur le développement - Le Best Of
    Réponses: 85
    Dernier message: 10/03/2009, 14h43
  2. choix sgbdr (encore!)
    Par _Gabriel_ dans le forum Décisions SGBD
    Réponses: 9
    Dernier message: 23/03/2004, 10h39
  3. TEdit (encore)
    Par dj.motte dans le forum C++Builder
    Réponses: 5
    Dernier message: 23/12/2002, 19h02
  4. TPalette (encore)
    Par Flipper dans le forum Langage
    Réponses: 3
    Dernier message: 28/11/2002, 23h45

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