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 operator=, héritage et fonction virtuelle pure


Sujet :

C++

  1. #1
    Membre éclairé Avatar de mchk0123
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    816
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Janvier 2007
    Messages : 816
    Points : 844
    Points
    844
    Par défaut surcharge operator=, héritage et fonction virtuelle pure
    Le code suivant précise dans la classe mère que l'operateur '=' doit être surchargé dans la classe fille. Or dès utilisation dans le main, il semblerait que l'aspect 'virtuel' de la surcharge ne fonctionne pas et qu'il cherche à appeller l'opérateur de la classe mère (non implémenté) plutôt que sa ré-écriture dans la classe fille !

    Bref, je comprend vraiment pas là ou j'ai faux :

    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
    #include <cstdlib>
    #include <cstdio>
    #include <ctime>
     
    class a {
      public:
        a();
        //virtual a& operator=(const a &ref) = 0;
        virtual a& set(const a &ref) = 0;
        void print() const;
      protected:
        int x;
    };
     
    class b : public a{
      public:
        //a& operator=(const a &ref);
        a& set(const a &ref);
    };
     
    a::a() {
      srand(time(NULL));
      x = rand();
    }
    void a::print() const {
      printf("x = %d\n", x);
    }
     
    /*
    a& b::operator=(const a &ref) {
      x = dynamic_cast<const b*>(&ref)->x;
     
      return *this;
    }
    */
    a& b::set(const a &ref) {
      x = dynamic_cast<const b*>(&ref)->x;
     
      return *this;
    }
     
    int main() {
      b x, y;
     
      x.print();
      //y = x;
      y.set(x);
      y.print();
     
      return 0;
    }
    Message d'erreur lors de l'édition de liens :

    main.o:main.cpp: (.text$_ZN1baSERKS_[b::operator=(b const&)]+0x14): undefined reference to `a::operator=(a const&)'
    collect2: ld returned 1 exit status
    Si j'utilise à la place de l'opérateur '=', la fonction 'set' la compilation passe bien.
    Avant de poster un message .
    Quand vous avez la réponse à votre question, n'oubliez pas de cliquer sur .

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

    Informations professionnelles :
    Activité : aucun

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

    Mais pourquoi voudrais tu donc fournir l'opérateur d'affectation en tant que fonction virtuelle pure

    Typiquement, une fonction virtuelle pure, c'est une fonction pour laquelle on ne dispose pas des informations nécessaire à sa définition...

    Or, tu dispose de toutes les informations pour te permettre de définir l'opérateur d'affectation... il n'y a donc a priori aucune raison qu'il ne soit virtuel pur

    De plus, rien ne t'empeche de déclarer une fonction virtuelle pure, mais de la définir avec un comportement par défaut, justement dans le cas où une classe dérivée venait à ne pas la réimplémenter

    Enfin, si ton seul but est de créer une classe non instanciable, tu peux toujours placer les constructeurs en acces protected, et implémenter l'ensemble des fonctions qui n'auraient pas lieu d'etre virtuelles pures

    Et, petite remarque en passant: tu aurais largement intéret à utiliser std::cout<< pour l'affichage, plutot que le printf() qui vient du C
    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

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

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 614
    Points : 30 626
    Points
    30 626
    Par défaut
    Je voudrais rajouter que, si ton but est d'empecher l'utilisation de l'opérateur d'affectation au profit de la fonction set(), rien ne t'empeche de le déclarer en visibilité private, mais de le déclarer...

    Et le fait que l'opérateur d'affectation doit, normalement, renvoyer une référence du type de l'objet passé...

    tu auras
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    a& operator(const a& ref);
    dans la classe a et
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    b& operator(const b& ref);
    dans la classe b

    Si, plus loin tu veux faire un
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    b bb;
    a aa=bb;//meme pas sur que cela compile, ceci dit :P
    cela se fait automatiquement, étant donné que tout b est un a, du fait de l'héritage

    [EDIT]ainsi que le fait que, si tu n'utilise pas des pointeurs au sein d'une classe, tu peux tres bien laisser le compilateur placer lui-meme le constructeur par copie et l'opérateur d'affectation... si, du moins, cela ne t'embete pas qu'ils soient en visibilité publique
    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

  4. #4
    Membre éclairé Avatar de mchk0123
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    816
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Janvier 2007
    Messages : 816
    Points : 844
    Points
    844
    Par défaut
    Merci de tes réponses koala.

    Voilà quelques petites précisons concernant ce que je voulais faire :

    - l'exemple de code que j'ai mis est un framework de collaboration entre classes
    - la classe a est uniquement une "interface"
    - elle ne possède que des méthodes virtuelles pures afin d'obliger les classes déscendante à implémenter chaque fonction de l'interface (sinon ça ne passe pas à la compilation)
    - cela sert également comme aide mémoire lors de l'extension du framework

    Donc la méthode virtuelle pure "operator=" est là dans a, uniquement pour forcer l'implémentation de la surcharge de cet opérateur dans b.

    Seulement voilà cette pratique trés propre au niveau de la conception se révèle délicate dans le cas de l'opérateur "=" puisque, comme tu l'as dit, chaque opérateur doit travailler sur la classe qui le définit. Donc typiquement on devrait avoir :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    a& a::operator=(const a &ref) {
    ...
    b& b::operator=(const b &ref) {
    ...
    Mais en faisant ça je perds 2 choses :
    - la capacité dans la classe mère a d'appeller l'opérateur virtuel "="
    - la notification par message d'erreur à la compilation dans le cas ou
    l'opérateur n'est pas surchargé dans b

    Donc je suis confronté à un dilemme :
    1. Se conformer à la notion d'interface virtuelle pure => pb : ne passe pas à la compilation
    2. Se conformer à la syntaxe de la surcharge de l'opérateur "=" => pb : voir les 2 ci-dessus

    Donc ma question est, dans la pratique, comment habituellement gérez-vous ce genre de situation ?
    Avant de poster un message .
    Quand vous avez la réponse à votre question, n'oubliez pas de cliquer sur .

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

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 614
    Points : 30 626
    Points
    30 626
    Par défaut
    Cela ne me pose aucun problème de conscience que de laisser à l'utilisateur le choix d'implémenter ou non son propre opérateur d'affectation...

    Surtout qu'à bien y réfléchir, le compilateur est parfaitement capable d'en fournir un tout à fait efficace, tant que l'on n'est pas dans le cadre d'une classe dont le constrcteur est du genre de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    Maclass::Maclass(/*...*/)
    {
        ptr=new type;
    }
    ou approchant...

    Par contre, ce qui peut s'avérer intéressant, c'est peut etre, ainsi que je te l'ai signalé plus haut, de faire passer le constructeur par copie et l'opérateur d'affectation dans une visibilité différente que la visibilité publique...

    Je le verrais bien dans une visibilité protected, histoire que seules les classes qui dépendent de l'interface puisse y accéder
    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

  6. #6
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    mchk0123 : Comme dit chez GotW, le mieux est de séparer l'interface virtuelle de l'implémentation.
    En clair, à ta place, je ferais ceci:
    Code C++ : 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
    class a
    {
    public:
        //Opérateur d'affectation non-virtuel
        a & operator=(a const & src)
        { VSet(src); return *this; }
    protected:
        //Fonction d'affectation virtuelle privée
        //(enfin, protected, car elle doit appeler celle de la classe mère)
        virtual void VSet(a const & src);
    };
     
    class b
    {
    protected:
        //Fonction d'affectation virtuelle privée
        //(enfin, protected, car elle doit appeler celle de la classe mère)
        virtual void VSet(a const & src);
    };
     
    void a::VSet(a const & src)
    {
        //...
    }
     
    void b::VSet(const a & src)
    {
        a::VSet(src);
        b const * pcB = static_cast< b const * >( &src );
        //...
    }
    Je n'ai pas essayé de compiler, mais c'est l'idée générale.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  7. #7
    Membre éclairé Avatar de mchk0123
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    816
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Janvier 2007
    Messages : 816
    Points : 844
    Points
    844
    Par défaut
    arf ... pas trop de le temps de répondre avant ce soir, mais vite fait :

    @koala01 : je vois 2 pbs :
    1. avoir un message d'erreur à la compilation (sur fonction virtuelle pure non implémentée) ça peut servir "d'aide mémoire" quand, x années plus tard, on veut spécialiser le pattern et qu'il est peu documenté

    2. ça encadre beaucoup plus l'utilisateur, si le pattern est une librairie que l'on livre à des clients (ou utilisateurs)

    @medinoc, oui ça se rapproche plus de ce que je veux faire, mais je penses que je mettrais VSet en virtuelle pure dans la classe mère. Je vais essayé ce soir. Merci.
    Avant de poster un message .
    Quand vous avez la réponse à votre question, n'oubliez pas de cliquer sur .

  8. #8
    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
    Ton probleme apparent est que le compilateur defini implicitement un membre operator=(b const&) dans la classe b qui appelle le membre operator=(a const&) de la classe a. Le message d'erreur t'indique qu'il a du mal a l'appeler (ce qui est normal vu qu'il est virtuel pur).

    Cet operateur d'assignation est appele quand tu fais
    Car il est une meilleure surcharge que b::operator=(a const&).

    Je n'ai pas le temps de regarder ce que la norme dit qu'il faut faire. Ca ne m'etonnerait pas que ce soit un bug de g++ de tenter la definition dans ce cas.

    Le probleme de fond, c'est qu' avoir une classe avec une semantique de valeur (et donc une assignation qui a du sens) est generalement incompatible avec une hierarchie concue pour fournir des membres virtuels (la raison est que pour que les membres virtuels se comportent comme tel, il faut manipuler des pointeurs ou des references, pas des valeurs). Les quelques cas ou les deux sont necessaires se traitent generalement par un proxy.
    Les MP ne sont pas là pour les questions techniques, les forums sont là pour ça.

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

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 614
    Points : 30 626
    Points
    30 626
    Par défaut
    Je comprent tres bien ton point de vue... mais...

    Est-ce que ton framework est réellement susceptible de poser problème si son utilisateur oublie de définir l'opérateur d'affectation, où n'est-ce qu'une "facilité" que tu souhaites implémenter
    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

  10. #10
    Membre éclairé Avatar de mchk0123
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    816
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Janvier 2007
    Messages : 816
    Points : 844
    Points
    844
    Par défaut
    Grace à medinoc j'ai une solution qui fonctionne.

    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
    #include <cstdlib>
    #include <ctime>
    #include <iostream>
     
    using namespace std;
     
    class a {
      public:
        a& operator=(const a &ref);
      protected:
        virtual void set(const a &ref) = 0;
    };
     
    class b : public a{
      public:
        b();
        using a::operator=;
        b& operator=(const b &ref);
        void print() const;
      protected:
        void set(const a &ref);
        void set(const b &ref);
      protected:
        int x;
    };
     
    a& a::operator=(const a &ref) {
      set(ref);
     
      return *this;
    }
     
    b::b() {
      x = rand();
    }
    b& b::operator=(const b &ref) {
      set(ref);
     
      return *this;
    }
    void b::set(const a &ref) {
      x = dynamic_cast<const b*>(&ref)->x;
    }
    void b::set(const b &ref) {
      x = ref.x;
    }
    void b::print() const {
      cout << "x = " << x << endl;
    }
     
    int main() {
      srand(time(NULL));
     
      b x, y;
      a *z;
     
      cout << "test1" << endl;
      x.print();
      y = x;
      y.print();
     
      cout << "test2" << endl;
      z = new b;
      ((b*) z)->print();
      // sans le using, message d'erreur de compilation (il fallait s'y attendre)
      y = *z;
      y.print();
     
      return 0;
    }
    Ca fait à peut prés ce que je veux, par contre je ne sais pas si c'est nickel au niveau conception et recommandation d'usage C++. Peut-être que l'on peut faire mieux.

    @JMB j'ai pas trop bien compris le lien entre la sémantique de valeur et le proxy. Normalement un proxy est unique (pas de surcharge d'interface) c'est son répresentation concrète qui change ; donc pour l'opérateur "=" virtuel pur il serait plutôt situé dans la classe mère de la réprésentation concrète, mais je ne risque pas avoir le même pb. de reconnaisance a::operator=(const a&) vs. b::operator=(const b&) ?
    Avant de poster un message .
    Quand vous avez la réponse à votre question, n'oubliez pas de cliquer sur .

  11. #11
    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
    Avant de te répondre, il faudrait que je comprenne ce que tu veux faire.

    Ici, je ne vois aucun intérêt à introduire la classe a:
    - elle n'offre aucun service.
    - lors de l'assignation d'un a à un b, tu supposes qu'en fait le a est un b (dynamic_cast sans vérifier le retour éventuel de NULL).
    Les MP ne sont pas là pour les questions techniques, les forums sont là pour ça.

  12. #12
    Membre éclairé Avatar de mchk0123
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    816
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Janvier 2007
    Messages : 816
    Points : 844
    Points
    844
    Par défaut
    Effectivement ça manque de précisions. Disons que j'ai simplifié au maximum pour bien cerner le message d'erreur du compilateur.

    Ma classe a est en fait une classe "Mouvement". J'ai également 2 autres classes : "Position" et "Gestionnaire".

    Une instance de mouvement peut s'appliquer à une instance position pour changer ses coordonnées (mouvement peut être considéré comme un vecteur de la position 1 à 2).

    La classe "Position" contient une instance de "Mouvement" car elle doit garder une trace du dernier mouvement ayant amené à la position courante.

    Enfin la classe gestionnaire sert à gérer un ensemble de positions et de mouvements.

    Tout ceci forme un motif de collaboration contenant des méthodes implémentées contenant du code assez générique. Dans ce code à un moment donné je dois sauver un mouvement dans une autre variable, d'ou l'operateur "=".

    Comme cet opérateur est nécessaire, je l'ai mis virtuel pur dans la classe "Mouvement".

    L'utilisation typique de ce motif, est de spécialiser "Mouvement" et "Position" par héritage (par exemple "Mouvement2D" et "Position2D", puis d'utiliser tel quel une instance de "Gestionnaire" pour lancer des calculs et algorithmes.
    Avant de poster un message .
    Quand vous avez la réponse à votre question, n'oubliez pas de cliquer sur .

  13. #13
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    void b::set(const a &ref) {
      x = dynamic_cast<const b*>(&ref)->x;
    }
    void b::set(const b &ref) {
      x = ref.x;
    }
    Duplication de code.
    Peut être évitée ainsi :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    void b::set(const a &ref) {
      //Oui, j'ai réappris le dynamic_cast<> de références entretemps.
      //Une exception std::bad_cast est lancée en cas de mauvais type,
      //Et ici je pense que c'est la meilleure chose à faire.
      set(dynamic_cast<const b&>(ref));
    }
    void b::set(const b &ref) {
      x = ref.x;
    }
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  14. #14
    Expert éminent sénior
    Avatar de Luc Hermitte
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2003
    Messages
    5 275
    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 275
    Points : 10 985
    Points
    10 985
    Par défaut
    Mon expérience m'a aussi fait converger vers la conclusion que sémantique de valeur et hiérarchies polymorphes sont incompatibles, et qu'en vérité je n'ai jamais eu besoin de supporter l'affectation sur des objets tirés d'une hiérarchie polymorphe.

    Maintenant, si vraiment tu veux cela, la solution tourne en effet autour de l'utilisation de proxys. Le contournement le plus célèbre est l'idiome enveloppe-lettre décrit par James O. Coplien. Et dernièrement, je suis tombé sur un articles d'Alex Stepanov sur les types réguliers (mauvaise traduction libre). cf l'article sur le wiki d'ASL (http://opensource.adobe.com/group__c...lar__type.html)
    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
    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
    Et dernièrement, je suis tombé sur un articles d'Alex Stepanov sur les types réguliers (mauvaise traduction libre). cf l'article sur le wiki d'ASL (http://opensource.adobe.com/group__c...lar__type.html)
    C'est la "forme normale" de Coplien, non? (Il faudrait que je reprenne le bouquin pour verifier qu'il n'y a pas une difference -- j'ai un doute sur la comparaison).
    Les MP ne sont pas là pour les questions techniques, les forums sont là pour ça.

  16. #16
    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
    Citation Envoyé par mchk0123
    ...
    Je suis desole mais ce n'est pas clair du tout.

    A priori je ne vois pas la necessite d'heritage entre des classes qui s'appelles "Mouvement", "Position" et "Gestionnaire". En fait, je ne saurais meme pas dans quel sens l'heritage se fait si tu n'avais ecrit:
    Comme cet opérateur est nécessaire, je l'ai mis virtuel pur dans la classe "Mouvement".
    Dans ce code à un moment donné je dois sauver un mouvement dans une autre variable, d'ou l'operateur "=".
    Il y a d'autres methodes que l'operateur = pour sauver un etat. Le pattern state par exemple, ou la definition d'un membre clone().

    Plus la discussion avance, plus j'ai l'impression que tu as un probleme de conception plus qu'un probleme technique d'implementation d'une conception. Et comme je ne comprends toujours pas le probleme, je lance des idees en l'air, mais il est possible sinon probable qu'elles ne soient pas pertinentes.
    Les MP ne sont pas là pour les questions techniques, les forums sont là pour ça.

  17. #17
    Expert éminent sénior
    Avatar de Luc Hermitte
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2003
    Messages
    5 275
    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 275
    Points : 10 985
    Points
    10 985
    Par défaut
    Citation Envoyé par Jean-Marc.Bourguet
    Et dernièrement, je suis tombé sur un articles d'Alex Stepanov sur les types réguliers (mauvaise traduction libre). cf l'article sur le wiki d'ASL (http://opensource.adobe.com/group__c...lar__type.html)
    C'est la "forme normale" de Coplien, non? (Il faudrait que je reprenne le bouquin pour verifier qu'il n'y a pas une difference -- j'ai un doute sur la comparaison).
    Je ne pense pas. La forme normale de Coplien correspond au fait qu'il faille régulièrement définir 4 opérations sur chaque classe.
    Là, les types réguliers sont définis comme un concept. Qui côté implémentation va se rapprocher de la forme normale de Coplien.

    Là où les types réguliers deviennent intéressants, c'est le mini-framework qui va transformer un type qui de base va plus être orienté vers une sémantique de référence, en un type qui va avoir une sémantique "régulière".

    Visiblement, je n'ai pas donné le lien vers l'article auquel je pensais. Sean Parent a écrit un article et une présentation sur le sujet mais je n'arrive pas à les retouver :-(
    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...

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

Discussions similaires

  1. Surcharge de fonction virtuelle pure
    Par lg_53 dans le forum C++
    Réponses: 4
    Dernier message: 07/11/2014, 15h26
  2. fonction virtuel pure et constante
    Par ZaaN dans le forum C++
    Réponses: 5
    Dernier message: 03/08/2007, 15h27
  3. Réponses: 2
    Dernier message: 30/01/2007, 11h44
  4. Réponses: 2
    Dernier message: 05/03/2006, 19h29
  5. Compilation avec des fonctions virtuel pure
    Par vanitom dans le forum C++
    Réponses: 4
    Dernier message: 16/12/2005, 14h37

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