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érateurs et héritage.


Sujet :

C++

  1. #1
    Membre confirmé
    Profil pro
    Étudiant
    Inscrit en
    Septembre 2006
    Messages
    112
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Septembre 2006
    Messages : 112
    Par défaut Surcharge d'opérateurs et héritage.
    Bonjour,

    J'ai une classe contenant certains opéateurs surchargés, que je dérive en une autre classe.
    Seulement les opérateurs dans la classe dérivée ne fonctionnent pas comme ils devraient, alors qu'ils fonctionnent impeccablement dans la classe de base.
    Auriez-vous une idéé sur l'origine du problème ?

    Voici les détails :

    Je définis dans ma classe de base les opérateurs que voici :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    virtual Vecteur& operator + (Vecteur);
    virtual Vecteur& operator = (const Vecteur&);
    et cela fonctionne très bien.
    Dans mon programme principal main je peux très bien écrire (pour des vecteurs v, w et z) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    v = w;
    w = (z + v);
    J'ai ensuite une classe polynôme, qui dérive (publiquement) de vecteur.
    Je ne prends pas la peine de redéfinir les opérateurs en question vu que leur fonctionnement est en tout point identique.
    Cependant pour trois polynômes a,b,c je peux écrire :

    mais si je tape :

    le compilateur me dit qu'il ne trouve pas le code de la fonction = correspondante.
    Cela me dépasse que cela fonctionne dans la classe de base mais pas dans la classe dérivée ...

    merci

  2. #2
    Membre Expert
    Avatar de Anthony.Desvernois
    Homme Profil pro
    Ingénieur sécurité & risque
    Inscrit en
    Juin 2007
    Messages
    1 489
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur sécurité & risque
    Secteur : Finance

    Informations forums :
    Inscription : Juin 2007
    Messages : 1 489
    Par défaut
    Bonjour,

    Peux tu donner le code de tes classes ?

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

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 641
    Par défaut
    Salut,

    Déjà une question sans doute un peu bête, mais, pourquoi déclarer ces opérateurs virtuels, s'il ne faut pas les redéfinir dans les classes dérivées

    Une autre question, sans doute tout aussi bête, mais, crois tu sincèrement réaliste de vouloir assigner un vecteur à... un complexe

    Enfin, la dernière question qui fâche: es tu sûr de pouvoir dire que, d'un point de vue sémantique, un (nombre) complexe est un vecteur

    La première réponse devrait t'inciter à supprimer le virtual de la déclaration des opérateurs pour ta classe vecteur.

    La seconde devrait t'inciter à malgré tout redéfinir l'opérateur d'affectation (qui fait partie de ce que l'on appelle les "Big four") pour ta classe complexe, du moins, si le comportement par défaut ne correspond pas à tes attentes (ce qui est sans doute le cas), mais en admettant qu'il ne s'agit normalement pas d'un comportement polymorphe.

    La troisième devrait t'inciter à réfléchir sur la réelle opportunité de déclarer un héritage
    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 confirmé
    Profil pro
    Étudiant
    Inscrit en
    Septembre 2006
    Messages
    112
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Septembre 2006
    Messages : 112
    Par défaut
    Désolé mais de quels complexes parles-tu ?
    Il est question de polynôme de degré maximal N, qui sont vu comme des cas particuliers de vecteurs à N dimensions vu que la seule chose qu'un polynôme possède en plus est la possibilité de l'évaluer en un point x et de connaître son degré.

    Ce n'est peut-être pas cohérent d'un point de vue orienté objet mais ça je n'y peux rien, c'est un projet que j'ai à faire pour un de mes cours et le professeur souhaite que ce soit fait ainsi

    J'ai l'intention de dériver d'autres choses de cette classe, ce pourquoi les opérateurs sont virtuels.
    Ici le comportement par défaut correspond à mes attentes justement, vu que additionner deux polynômes revient à additionner leurs coefficients qui sont les composantes d'un vecteur de R^N.

    Sinon avez-vous besoin du code de toutes les classes en entier ?
    Parceque c'est long et ça sera lourd si je copie colle tout ça ici.

    Voici en tout le code de l'opérateur = :
    (et oui petite précision ma classe vecteur est une classe template )

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    template <typename Elem, size_t DIM>
    Vecteur<Elem,DIM>& Vecteur<Elem,DIM>::operator = (const Vecteur &V)
    {
         if (&V != this)
         {
             for (size_t i = 0; i < DIM; i++)
                this->val_[i] = V.val_[i];
         }
         return *this;
    }
    Si vous voulez le reste du code je peux auss le mettre.

    merci beaucoup.

  5. #5
    Membre éclairé
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    36
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2007
    Messages : 36
    Par défaut
    Citation Envoyé par Opérateur Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    template <typename Elem, size_t DIM>
    Vecteur<Elem,DIM>& Vecteur<Elem,DIM>::operator = (const Vecteur<Elem,Dim> &V)
    {
         if (&V != this)
         {
             for (size_t i = 0; i < DIM; i++)
                this->val_[i] = V.val_[i];
         }
         return *this;
    }
    Peut-être qu'en respecifiant les param de template cela fonctionnera mieux (bon j'avoue, je ne suis pas sur)

  6. #6
    Membre confirmé
    Profil pro
    Étudiant
    Inscrit en
    Septembre 2006
    Messages
    112
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Septembre 2006
    Messages : 112
    Par défaut
    Ah, il y a un problème avec les paramètres de template

    merci

  7. #7
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 641
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 641
    Par défaut
    Citation Envoyé par Opérateur Voir le message
    Désolé mais de quels complexes parles-tu ?
    Il est question de polynôme de degré maximal N, qui sont vu comme des cas particuliers de vecteurs à N dimensions vu que la seule chose qu'un polynôme possède en plus est la possibilité de l'évaluer en un point x et de connaître son degré.
    Au temps pour moi... j'avais bien lu polynôme, et ca s'est transformé - va savoir pourquoi - dans ma tête en "complexe"
    Ce n'est peut-être pas cohérent d'un point de vue orienté objet mais ça je n'y peux rien, c'est un projet que j'ai à faire pour un de mes cours et le professeur souhaite que ce soit fait ainsi
    Ah, ces profs qui n'arrivent pas à concevoir correctement l'orienté objet ()
    J'ai l'intention de dériver d'autres choses de cette classe, ce pourquoi les opérateurs sont virtuels.
    Ici le comportement par défaut correspond à mes attentes justement, vu que additionner deux polynômes revient à additionner leurs coefficients qui sont les composantes d'un vecteur de R^N.
    Mais, le fait de vouloir (sans doute à juste titre, du moins, en partant du principe que ) dériver une classe pour laquelle tu définis n'importe quel opérateur (que ce soit l'opérateur d'assignation ou un autre) ne rend pas cet opérateur polymorphe pour autant...

    Prenons l'exemple de l'opérateur d'assignation, car c'est celui dont on parle, mais le raisonnement est applicable à tous les autres...

    Si tu as une classe de base nommée A et plusieurs (finalement pourquoi pas ) classe dérivées nommées B, C, D et E qui héritent de la classe de base:
    • Tu vas souvent assigner un objet de type A à une variable type A
    • Tu vas parfois assigner un objet de type B (ou C ou D ou E) à une variable de type A... mais comme l'objet de type B (ou C ou D ou E) peut passer pour un objet de type A, l'opérateur d'assignation de A suffit (de toutes manières, tu traitera ta variable comme s'il s'agissait d'un objet de type A, bien que tu fasse sans doute appel à des comportements polymorphes )
    • Tu vas souvent assigner un objet de type B (ou C ou D ou E) à une autre variable de type B (ou respectivement C, D ou E), mais, à ce moment là, c'est l'opérateur (non polymorphe) de la classe en question qui est utilisé.
    • Par contre, tu ne vas sans doute pas assigner un objet de type B à une variable de type C, D ou E, ou, si tu veux le faire, ce ne sera pas l'opérateur d'assignation qui devra être utilisé, mais un opérateur de conversion...

    Tu te rend bien compte que les opérateurs n'ont finalement jamais aucune raison d'être polymorphe, même s'il peuvent appeler une fonction qui l'est, pour adapter un comportement attendu au type réellement utilisé

    Dans la FAQ, tu trouve un exemple adapté à l'opérateur <<, mais le raisonnement est strictement identique
    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

  8. #8
    Membre confirmé
    Profil pro
    Étudiant
    Inscrit en
    Septembre 2006
    Messages
    112
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Septembre 2006
    Messages : 112
    Par défaut
    Ahhhh oui je crois que comprend maintenant

    C'est évident, j'aurais dû y penser.
    Mais donc, je vais devoir redéfinir tous mes opérateurs dans la classe dérivée ? Ca serait bête vu que le code est exactement pareiln il n'y a que la valeur de retour qui va changer ...

    merci

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

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 641
    Par défaut
    Citation Envoyé par Opérateur Voir le message
    Ahhhh oui je crois que comprend maintenant

    C'est évident, j'aurais dû y penser.
    Mais donc, je vais devoir redéfinir tous mes opérateurs dans la classe dérivée ? Ca serait bête vu que le code est exactement pareiln il n'y a que la valeur de retour qui va changer ...

    merci
    ... Et le type de l'argument

    En effet, il est peu probable que tu essaye d'assigner autre chose qu'un objet de type B (ou de type dérivé) à une variable de type B

    Et donc, tu devra effectivement définir l'opérateur dans chaque classe qui en a besoin (si le comportement par défaut ne correspond pas pour le cas de l'opérateur d'assignation)

    Mais cela implique que, si tu en viens à vouloir assigner autre chose qu'un objet de type B, il faut que tu prévoie la conversion

    Peut être l'idiome copy and swap te sera-t-il utile
    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 confirmé
    Profil pro
    Étudiant
    Inscrit en
    Septembre 2006
    Messages
    112
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Septembre 2006
    Messages : 112
    Par défaut
    ah bon, ok.

    Je crois que je comprend mieux à présent, merci beaucoup pour toutes les explications si détaillées, c'est vraiment gentil

+ 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