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 :

Surcharge d'opérateur unaire


Sujet :

C++

  1. #1
    Membre régulier
    Homme Profil pro
    Étudiant
    Inscrit en
    Octobre 2003
    Messages
    88
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2003
    Messages : 88
    Points : 73
    Points
    73
    Par défaut Surcharge d'opérateur unaire
    Salut à tous!
    Je cherche à surcharger l'opérateur unaire - dans un cadre d'héritage. Je voudrais faire quelque chose comme cela:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    class Number_template
    {
    virtual Number_template operator-( );
    };
     
    class Number : public Number_template
    {
    Number operator-( );
    };
    Apparemment, pour que cela fonctionne, je devrais retourner non pas un Number mais un pointeur vers un Number. Mais je ne vois pas trop comment faire.

    Quelqu'un à une idée?

    Merci!

    Rafael
    "On dit que seulement 10 personnes au monde comprenaient Einstein. Personne ne me comprends. Suis-je un génie???"

  2. #2
    Membre éprouvé
    Avatar de mitkl
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2010
    Messages
    364
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2010
    Messages : 364
    Points : 1 081
    Points
    1 081
    Si vous ne savez toujours pas ce qu’est la récursivité, relisez cette phrase.

    Mon blog sur la programmation et l'informatique !

  3. #3
    Membre régulier
    Homme Profil pro
    Étudiant
    Inscrit en
    Octobre 2003
    Messages
    88
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2003
    Messages : 88
    Points : 73
    Points
    73
    Par défaut
    Merci pour ta réponse.

    J'y ai pensé mais ce qui change fondamentalement (je pense, mais peut être que je passe à côté de quelque chose), c'est que mon opérateur unaire ne modifie pas l'objet, donc je peux pas retourner *this. Du coup, je vois pas trop sur quoi retourner un pointeur...
    "On dit que seulement 10 personnes au monde comprenaient Einstein. Personne ne me comprends. Suis-je un génie???"

  4. #4
    Membre actif
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    159
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2008
    Messages : 159
    Points : 224
    Points
    224
    Par défaut
    Pourquoi devrais-tu retourner un pointeur ?
    Habituellement l'opérateur unaire de négation renvoie par copie un nouvel objet.

    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
     
    #include <iostream>
     
    class A
    {
        int m_x;
     
    public:
     
        A(int x)
        {
            m_x = x;
        }
     
        int getx() const
        {
            return m_x;
        }
     
        A operator-() const
        {
            return A(-m_x);
        }
     
    };
     
    int main(int argc, char **argv)
    {
        A a(3);
        std::cout << "a.getx() : " << a.getx() << std::endl;
        std::cout << "-a.getx() : " << (-a).getx() << std::endl;
        return 0;
    }
    compile et donne à l'exécution :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    a.getx() : 3
    -a.getx() : -3

  5. #5
    Membre régulier
    Homme Profil pro
    Étudiant
    Inscrit en
    Octobre 2003
    Messages
    88
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2003
    Messages : 88
    Points : 73
    Points
    73
    Par défaut
    valAa: car je fais de l'héritage. J'ai l'impression que sinon cela ne fonctionne pas (car les méthodes n'ont plus la même signature).
    "On dit que seulement 10 personnes au monde comprenaient Einstein. Personne ne me comprends. Suis-je un génie???"

  6. #6
    Inactif  


    Homme Profil pro
    Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Inscrit en
    Décembre 2011
    Messages
    9 012
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2011
    Messages : 9 012
    Points : 23 145
    Points
    23 145
    Par défaut
    Ceci devrait marcher :

    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
     
    //soit A la classe mère.
     
    //dans A :
    virtual const A operator-(const A & a) const
        {
            /* tu définis un constructeur qui prenne en paramètre un const A & et un const A &
    qui construise ton objet comme tu le souhaites. */
            return A(*this, a);
        }
     
    //dans la classe fille :
     const [Type Classe Fille] operator-(const A & a) const
        {
            /* tu définis un constructeur qui prenne en paramètre un const [Type Classe Fille] & et un const A &
    qui construise ton objet comme tu le souhaites. */
            return [Type Classe Fille](*this, a);
        }
     
    OU
     
    //dans A :
    virtual const A operator-() const
        {
            /* tu définis le constructeur selon ce qui t'arrange */
            return A(...);
        }
     
    //dans la classe fille :
     const [Type Classe Fille] operator-() const
        {
            /*tu définis le constructeur selon ce qui t'arrange */
            return [Type Classe Fille](...);
        }
    renvoyer une copie ne marcherais pas puisque si on retournerais à chaque fois une instance de la classe mère et non une instance de la classe fille.

    EDIT : le type de retour n'est pas pris en compte lors de la résolution du compilateur.

  7. #7
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 115
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 115
    Points : 32 965
    Points
    32 965
    Billets dans le blog
    4
    Par défaut
    Bonjour,

    la définition de l'opérateur - est
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    struct C {
     C operator-() const;
    };
    Puisqu'il s'agit d'un retour par valeur, l'héritage pose 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
    struct C {
          int x;
          int y;
          C() : x(0), y(0) {}
          C(int _x, int _y) : x(_x), y(_y) {}
          C operator-() const { return C(-x, -y); }
          virtual void cout() const { std::cout<<"x:"<<x<<",y:"<<y<<std::endl; }
       };
       struct D : public C {
          int z;
          D() : C(0,0), z(0) {}
          D(int _x, int _y, int _z) : C(_x,_y), z(_z) {}
          D operator-() const { return D(-x, -y, -z); }
          virtual void cout() const { std::cout<<"x:"<<x<<",y:"<<y<<",z:"<<z<<std::endl; }
       };
     
       C* c = new D(1,2,3);
       c->cout();
       (-(*dynamic_cast<D*>(c))).cout();
    Un peu indigeste, mais la seule solution amha.

    Du coup, une solution plus propre serait
    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
    struct C {
          int x;
          int y;
          C() : x(0), y(0) {}
          C(int _x, int _y) : x(_x), y(_y) {}
          virtual void reverse(C*& _c) const { _c = new C(-x, -y); }
          virtual void cout() const { std::cout<<"x:"<<x<<",y:"<<y<<std::endl; }
       };
       struct D : public C {
          int z;
          D() : C(0,0), z(0) {}
          D(int _x, int _y, int _z) : C(_x,_y), z(_z) {}
          virtual void reverse(C*& _c) const { _c = new D(-x, -y, -z); }
          virtual void cout() const { std::cout<<"x:"<<x<<",y:"<<y<<",z:"<<z<<std::endl; }
       };
     
       C* c = new D(1,2,3);
       c->cout();
       C* c2;
       c->reverse(c2);
       c2->cout();
    Il faudra juste avoir une attention aux fuites mémoires. Attention assez faible je pense puisque tu es déjà sur du pointeur/référence.
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  8. #8
    Membre régulier
    Homme Profil pro
    Étudiant
    Inscrit en
    Octobre 2003
    Messages
    88
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2003
    Messages : 88
    Points : 73
    Points
    73
    Par défaut
    @Neckara, Bousk: merci pour vos réponses.
    J'ai une question stupide: comment cela se passe pour la libération de la mémoire (puisque je fais un new explicite)? Du coup, je dois le faire manuellement, non? Et cela devient un code un peu délicat.

    Y-a-t-il une solution standard dans ce genre de cas?
    "On dit que seulement 10 personnes au monde comprenaient Einstein. Personne ne me comprends. Suis-je un génie???"

  9. #9
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 115
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 115
    Points : 32 965
    Points
    32 965
    Billets dans le blog
    4
    Par défaut
    Puisque tu as un new, tu dois avoir un delete.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
       C* c = new D(1,2,3);
       C* c2;
       c->reverse(c2);
      // do stuff with c2
      // c2 now useless
      delete c2;
      // probably delete c; maybe elsewhere
    Il y a peut-être un smart_pointer qui peut faire cela, aucune idée.
    Mais il n'y a aucune difficulté à ça.
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  10. #10
    Membre régulier
    Homme Profil pro
    Étudiant
    Inscrit en
    Octobre 2003
    Messages
    88
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2003
    Messages : 88
    Points : 73
    Points
    73
    Par défaut
    Parfait, merci!
    "On dit que seulement 10 personnes au monde comprenaient Einstein. Personne ne me comprends. Suis-je un génie???"

  11. #11
    Inactif  


    Homme Profil pro
    Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Inscrit en
    Décembre 2011
    Messages
    9 012
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2011
    Messages : 9 012
    Points : 23 145
    Points
    23 145
    Par défaut
    Je me pose tout de même une question :

    Puisqu'il s'agit d'un retour par valeur, l'héritage pose problème.
    Est-ce vraiment le cas ? Comme le type de retour n'est pas pris en compte, toutes les méthodes ne se différenciant que par leur type de retours sont considérée comme étant une même et unique méthode (d'où des erreurs lors de la compilation).

    Pourquoi ne pourrait-on pas mettre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    virtual C operator-() const { return C(-x, -y); }
    //et
     D operator-() const { return D(-x, -y, -z); }
    Théoriquement ceci devrait fonctionner vu que le compilateur ne devrait pas tenir compte du code de retour lors de la résolution à moins que je ne me trompe ?

    Je pense qu'il faudrait au maximum éviter de faire un new sans libérer soit-même avec un delete.

    Et si tu ne passais pas par des méthodes mais par un ensemble de fonctions amies (pouvant éventuellement appeler des méthodes privées des membres)?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    A operator-(const & A);
    D operator-(const & D);
    Ainsi tu ne devrais plus avoir de problèmes (?)

  12. #12
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 115
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 115
    Points : 32 965
    Points
    32 965
    Billets dans le blog
    4
    Par défaut
    Fais le test et tu verras que jamais tu n'apelleras jamais D operator-(). Quand bien même C operator-() est virtual.
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  13. #13
    Inactif  


    Homme Profil pro
    Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Inscrit en
    Décembre 2011
    Messages
    9 012
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2011
    Messages : 9 012
    Points : 23 145
    Points
    23 145
    Par défaut
    En effet.

    Il y a deux autres solutions possible il me semble :
    - utiliser une fonction et non une méthode (je ne sais pas si ça marche)
    - ne pas mettre d'héritage et mettre un template dans la fonction appelante.

  14. #14
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 612
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 612
    Points : 30 612
    Points
    30 612
    Par défaut
    Salut,

    Il ne faut pas oublier une chose : l'opérateur - (tout comme n'importe quel opérateur de sémantique plus ou moins mathématique ) est, typiquement, un opérateur destiné à une classe ayant sémantique de valeur (parce qu'il provoquent, justement, une copie de l'objet et que la copie est incompatible avec une sémantique d'entité) !!!

    Or, l'hértiage (public) est, au contraire, destiné à des classes ayant sémantique d'entité

    J'aurais presque envie de dire que, de toute évidence, il y a une incompatibilité entre deux des besoins que tu sembles mettre en évidence :

    D'un coté, tu voudrais que ta classe aie typiquement sémantique de valeur, alors que, de l'autre, tu voudrais profiter de l'héritage et donc avoir une classe ayant sémantique d'entité

    Les bonnes questions à se poser semblent donc être :
    Es tu sur que l'héritage est la solution la plus adaptée à ton problème
    Est-ce que l'héritage (public) que tu envisages respecte le sacro saint LSP (Liskov Substitution Principle)
    As tu plus besoin de l'opérateur ou de l'héritage (si tant est que LSP soit respecté)
    Est-ce que ton opérateur - est compatible avec la sémantique que tu voudrais lui donner n'aurais tu pas plutot intérêt à créer une fonction nommée substract quel devrait etre le résultat de cette focntion créer un nouvel objet, ou modifier l'objet au départ duquel elle est invoquée
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  15. #15
    Membre régulier
    Homme Profil pro
    Étudiant
    Inscrit en
    Octobre 2003
    Messages
    88
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2003
    Messages : 88
    Points : 73
    Points
    73
    Par défaut
    Salut koala01,
    Merci d'apporter un nouveau point de vue à cette discussion.

    Mon but est de créer un certain ensemble de classes permettant de représenter des nombres (une pour des nombres rationnels, une pour des nombres complexes, une pour des éléments d'un corps finis à p éléments, ...). Du coup, je voulais créer une classe mère qui m'assurerait que toutes les classes enfant implémentent effectivement les différentes opérations dont j'ai besoin (surcharge d'opérateurs et 2-3 autres choses). La raison pour laquelle j'ai choisi de ne pas faire de templates et me diriger vers de l'héritage est que mes opérateurs sont trop spécifiques aux différentes classes enfants.

    Aurais-je du faire différemment?

    Merci!

    Raf
    "On dit que seulement 10 personnes au monde comprenaient Einstein. Personne ne me comprends. Suis-je un génie???"

  16. #16
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 612
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 612
    Points : 30 612
    Points
    30 612
    Par défaut
    Citation Envoyé par raf_gug Voir le message
    Salut koala01,
    Merci d'apporter un nouveau point de vue à cette discussion.
    De rien
    Mon but est de créer un certain ensemble de classes permettant de représenter des nombres (une pour des nombres rationnels, une pour des nombres complexes, une pour des éléments d'un corps finis à p éléments, ...). Du coup, je voulais créer une classe mère qui m'assurerait que toutes les classes enfant implémentent effectivement les différentes opérations dont j'ai besoin (surcharge d'opérateurs et 2-3 autres choses). La raison pour laquelle j'ai choisi de ne pas faire de templates et me diriger vers de l'héritage est que mes opérateurs sont trop spécifiques aux différentes classes enfants.

    Aurais-je du faire différemment?

    Merci!

    Raf
    Justement, à partir du moment où l'on peut envisager le fait que tu ne commencera pas à mélanger des nombres rationnels avec des complex ou avec des entiers, c'est bel et bien vers les templates que tu devrais t'orienter

    Autrement, cela signifie que tu envisages (par exemple, hein ) de pouvoir écrire monEntier - monComplexe, et obtenir quelque chose qui devrait se situer "quelque part" entre l'entier et le complexe or, cela n'a pas vraiment de sens

    Tu peux, effectivement, envisager de le faire, mais ca devrait se gérer au niveau d'une classe proche de "opération" et mettrait sans doute en oeuvre un fonctionnement proche de celui de boost::any

    De plus, et je confirme là ce que j'ai dit plus haut, dés que l'on parle de valeur, on se trouve face à des objets ayant... sémantique de valeur, justement (dont, entre autres, il peut exister plusieurs instances identiques et comparable par égalité), et, il n'y a rien à faire : si une classe ayant sémantique d'entité peut ne pas intervenir dans une hiérarchie d'héritage, une classe ayant sémantique de valeur n'interviendra jamais dans une hiérarchie de classes
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  17. #17
    Membre émérite
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    2 764
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 2 764
    Points : 2 704
    Points
    2 704
    Par défaut
    Citation Envoyé par koala01 Voir le message
    Or, l’héritage (public) est, au contraire, destiné à des classes ayant sémantique d'entité
    J'aimerais bien que tu m'orientes vers des sources à ce sujet, car j'ai du mal à comprendre pourquoi.

  18. #18
    En attente de confirmation mail

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Août 2004
    Messages
    1 391
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : France, Doubs (Franche Comté)

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

    Informations forums :
    Inscription : Août 2004
    Messages : 1 391
    Points : 3 311
    Points
    3 311
    Par défaut
    @oodini: Il faut bien voir que l'implication est dans le sens héritage publique => sémantique d'entité (*), et pas dans l'autre. Dit autrement, avoir une classe à sémantique d'entité n'est pas symptomatique d'un héritage publique.

    Le sens de cette implication ne vient pas tant du fait des classes à sémantique d'entité, mais de celles à sémantique de valeur qui elles sont incompatibles avec l'héritage publique

    Plus exactement c'est l'héritage publique et la sémantique de copie qui sont incompatible avec la dualité valeur/entité.

    En effet, une des différence entre les deux sémantiques est le caractère copiable :

    -> Une entité ne peut être copiable, si une entité était copiable alors l'entité résultant et l'entité d'origine doivent être considérées comme identiques (c'est le sens d'une sémantique de copie), or deux entités différentes (au sens des objets) ne peuvent être identique (c'est le sens d'une sémantique d'entité).

    ->Une valeur est copiable, mais une valeur et sa copie résultante doivent être considérées comme identiques (bien qu'elles sont différentes au sens des objets), ceci se caractérise par les comportements de l'ensemble de l'interfaces qui doivent être invariables. Ce qui est incompatible avec l'héritage publique (l'héritage (**) est un moyen d'introduire un point de variation de l'interface et/ou de ses comportements (***), il n'a pas de raison d'être sinon).

    NB: Ca ne reste que mon point de vue personnel

    (*) Cette implication héritage publique => sémantique d'entité reste quand même propre à la conception objets et à la dualité entité/valeur. Des besoins plus orienté technique que métier peuvent amener un héritage publique sans considerer cette dualité.

    (**) Ici c'est général et ne s'applique pas qu'à l'héritage publique, dans le cas d'un héritage restrient (protégé ou privé) ce point de variation se retrouvé limité au sein de la hiérarchie, sans ce besoin alors un sous-objet membre est surment plus indiqué.

    (***) Ici c'est général et ne s'applique pas qu'à la dualité entité/valeur, l'usage d'un héritage devrait toujours résulter d'un besoin d'introduire un point de variation dans l'interface et ses comportement.

  19. #19
    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 Neckara Voir le message
    Pourquoi ne pourrait-on pas mettre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    virtual C operator-() const { return C(-x, -y); }
    //et
     D operator-() const { return D(-x, -y, -z); }
    Soit tu masques si la fonction de la classe de base n'est pas virtuelle, soit tu dois avoir un retour co-variant de par la norme
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    struct base
    {
       base foo();
       virtual base& bar();
       virtual base error();
    };
     
    struct derived : base
    {
       int foo(); // masque la fonction de la classe de base et peut dès lors retourner n'importe quoi
       virtual derived& bar(); // OK derived& est un retour co-variant de base&
       virtual derived error(); // erreur derived n'est pas un retour co-variant de base
    };
    Le retour covariant des fonctions virtuelles


    Sinon pour tout ce qui est héritage, opérateur, sémantique de valeur/entité, 100% d'accord avec ce qui a été dit précédemment.
    Rappel : F.A.Q. Quand est-ce qu'une classe a une sémantique de valeur ?
    F.A.Q Quand est-ce qu'une classe a une sémantique de d'entité ?

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

Discussions similaires

  1. [C#] Tri d'objet et surcharge d'opérateur
    Par Royd938 dans le forum Windows Forms
    Réponses: 6
    Dernier message: 17/12/2007, 00h26
  2. Petit probléme de surcharge d'opérateur .
    Par Clad3 dans le forum C++
    Réponses: 20
    Dernier message: 11/04/2005, 20h15
  3. Problème de surcharge d'opérateurs
    Par Hell dans le forum C++
    Réponses: 17
    Dernier message: 17/01/2005, 16h01
  4. Cumul de surcharges d'opérateurs
    Par Nats dans le forum C++
    Réponses: 2
    Dernier message: 11/10/2004, 13h37
  5. [VB .NET] Surcharge d'opérateur
    Par Franckintosh dans le forum VB.NET
    Réponses: 2
    Dernier message: 07/09/2004, 19h05

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