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 :

[POO] problème de surcharge des parenthèses


Sujet :

C++

  1. #1
    Membre régulier
    Homme Profil pro
    Software engineer
    Inscrit en
    Août 2008
    Messages
    139
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations professionnelles :
    Activité : Software engineer

    Informations forums :
    Inscription : Août 2008
    Messages : 139
    Points : 92
    Points
    92
    Par défaut [POO] problème de surcharge des parenthèses
    salut
    je suis entrain d'ecrire une classes fraction dont j'ai besoin de surcharger les opérateur + << >> > < et () ,j'ai tout fais mais j'arrive pas a surcharger les parentheses !
    l'idée est la suivante:
    surchager les () pour que, par exemple (1/4) retourne un objet de type fraction.
    j'espère que vous me donner un coup de main.
    merci d'avance

  2. #2
    Membre éclairé
    Avatar de Florian Goo
    Profil pro
    Inscrit en
    Septembre 2008
    Messages
    680
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Septembre 2008
    Messages : 680
    Points : 858
    Points
    858
    Par défaut
    Bonjour,

    En gros, tu voudrais pouvoir écrire ça :
    ?

  3. #3
    Alp
    Alp est déconnecté
    Expert éminent sénior

    Avatar de Alp
    Homme Profil pro
    Inscrit en
    Juin 2005
    Messages
    8 575
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Juin 2005
    Messages : 8 575
    Points : 11 861
    Points
    11 861
    Par défaut
    Je doute que ce soit possible, car l'expression 1/4 sera évaluée... On pourrait se dire que surcharger "/" pour les entiers marcherait, mais je doute que ça fonctionne.

    La solution qui semble la plus raisonnable, c'est :
    Mais il s'agit ici du constructeur...
    Surcharger les parenthèses servirait éventuellement à changer la valeur de la fraction :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Fraction f(1, 4);
    f(2, 3); // f = 2/3 maintenant

  4. #4
    Membre éclairé
    Avatar de Florian Goo
    Profil pro
    Inscrit en
    Septembre 2008
    Messages
    680
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Septembre 2008
    Messages : 680
    Points : 858
    Points
    858
    Par défaut
    J'attendais de savoir ce qu'il voulais vraiment
    Ce qui est sûr c'est que l'utilisation de la surcharge de l'opérateur parenthèse ne donnera pas quelque chose de très intuitif (voire totalement contre-intuitif) !

    On pourrait faire un truc avec Boost.Proto ?

  5. #5
    Alp
    Alp est déconnecté
    Expert éminent sénior

    Avatar de Alp
    Homme Profil pro
    Inscrit en
    Juin 2005
    Messages
    8 575
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Juin 2005
    Messages : 8 575
    Points : 11 861
    Points
    11 861
    Par défaut
    Citation Envoyé par Florian Goo Voir le message
    On pourrait faire un truc avec Boost.Proto ?
    Probablement

    Mais pour _un seul type_ ça fait un peu lourd

  6. #6
    Membre régulier
    Homme Profil pro
    Software engineer
    Inscrit en
    Août 2008
    Messages
    139
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations professionnelles :
    Activité : Software engineer

    Informations forums :
    Inscription : Août 2008
    Messages : 139
    Points : 92
    Points
    92
    Par défaut
    merci pour vos interventions et voici le probleme :
    l'utilisateur doit donner une expression , exemp : (1/7)+(2/3)+(4/3)
    je suis demandé de :
    -stocker les fractions dans une liste doublement chainée circulaire
    -surcharger les opérateurs << >> < > + ()
    -ce travail doit me permettre de manipuler l'expression comme calculer la somme des fractions , comparer les fractions etc

    logiquement la surcharge des () doit porter sur les fractions .
    pour le moment j'ai essayer de surcharger << et >> sur le type Fraction et ça marche mais avec un surcharge de () je crois
    que le compilateur doit etre capable de prendre du flux entrant tout un (1/7) et la stocker comme Fraction dans une
    cellule de la liste.
    j'èspere que j'ai bien mis au point le probleme,si mon idée parait non faisable veuillez me dire pourquoi et me proposer une autre si c'est possible
    a propos ! c'est vraiment un forum vivant !

    voila j'ai commencer a essayer ça :
    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
     
    /*********Fraction.h*************/
    #include<iostream>
    #include <iomanip>
    using namespace std;
     
    class Fraction{
        public:
        Fraction();
        Fraction(int numerateur);
        Fraction(int numerateur, int denominateur);
        int getNumerateur();
        int getDenominateur();
        void setNumerateur(int );
        void setDenominateur(int );
        bool operator<(const Fraction &frac);
        bool operator>(const Fraction &frac);
        Fraction& operator+(const Fraction &frac);
     
        private:
        int m_numerateur;
        int m_denominateur;
    };
    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
     
    /*******Fraction.cpp**************/
    #include "fraction.h"
     
    Fraction::Fraction(int numerateur,int denominateur){
        m_numerateur=numerateur;
        m_denominateur=denominateur;
    }
     
    Fraction::Fraction(int numerateur){
        m_numerateur=numerateur;
        m_denominateur=1;
    }
     
    Fraction::Fraction(){
        m_numerateur=0;
        m_denominateur=0;
    }
     
     
    int Fraction::getNumerateur(){
        return m_numerateur;
    }
     
    int Fraction::getDenominateur(){
        return m_denominateur;
    }
     
    void Fraction::setNumerateur(int numerateur){
        m_numerateur=numerateur;
    }
     
    void Fraction::setDenominateur(int denominateur){
        m_denominateur=denominateur;
    }
     
    bool Fraction::operator<(const Fraction &frac){
        int numerateur=m_numerateur;
        int denominateur=m_denominateur;
        int num=frac.m_numerateur;
        num=frac.m_numerateur*denominateur;
        numerateur=numerateur*frac.m_denominateur;
        denominateur=frac.m_denominateur*denominateur;
        num=denominateur;
        if (numerateur<m_numerateur) return true;
        else return false;
    }
     
     
    bool Fraction::operator>(const Fraction &frac){
        int numerateur=m_numerateur;
        int denominateur=m_denominateur;
        int num=frac.m_numerateur;
        num=frac.m_numerateur*denominateur;
        numerateur=numerateur*frac.m_denominateur;
        denominateur=frac.m_denominateur*denominateur;
        num=denominateur;
        if (numerateur>m_numerateur) return true;
        else return false;
    }
     
     
    Fraction& Fraction::operator+(const Fraction &frac){
        int numerateur=m_numerateur;
        int denominateur=m_denominateur;
     
        numerateur=frac.m_numerateur*denominateur+numerateur*frac.m_denominateur;
        denominateur=frac.m_denominateur*denominateur;
     
        Fraction res(numerateur,denominateur);
     
        return res;
    }
    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
     
    /*********main.cpp************/
    #include "fraction.h"
     
    ostream& operator<<(ostream& os, Fraction& frac){
        os << frac.getNumerateur();
        os << "/";
        os << frac.getDenominateur();
        return os;
    }
     
    istream& operator>>(istream& is, Fraction& frac){
        int a;
        cout << "Entrez une fraction " << endl;
        is >> setw(1) >> a;
        frac.setNumerateur(a);
        is.ignore();
        is >> setw(1) >> a;
        frac.setDenominateur(a);
        return is;
    }
     
     
    int main(){
        Fraction frac1;
        cin >> frac1;
        Fraction frac2;
        cin >> frac2;
        Fraction res;
        res=frac1+frac2;
        cout << frac1 << " + " << frac2 << " = " << res << endl;
        if (frac1<frac2) cout << frac1 << " < " << frac2 << endl;
        if (frac1>frac2) cout << frac1 << " > " << frac2 << endl;
        return 0;
    }
    ça marche bien mais maintenant je doit le fait évoluer pour qu'il prend tout une expression et la stocke dans une liste que je l'ai déja écrit a part :
    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
     
    /*********Expression.h**************/
    #include <iostream>
     
    using namespace std;
     
    class Expression{
        public:
        Expression();
        Expression& insert(int val);
        void affiche();
        ~Expression();
     
        struct ElementListe {
            int  donnee;
            ElementListe *suivant;
            ElementListe *precedent;
        };
     
     
        private:
        int taille;
        ElementListe *debut;
        ElementListe *fin;
    };
    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
     
    /*********Expression.cpp*************/
    #include "Expression.h"
     
    Expression::Expression(){
        debut = NULL;
        fin = NULL;
        taille = 0;
    }
     
    Expression::~Expression(){
        /* si la liste est vide, il n'y a rien à faire
         * il n'y a que si elle ne l'est pas qu'il faudra tout libérer
         */
        if(debut!=0)
        {
            /* il va nous falloir deux pointeurs "temporaires":
             * le premier pour représenter l'élément à supprimer,
             * le second pour représenter l'élément qui suit celui que l'on
             * s'apprête à supprimer
             *
             * Le premier élément que nous supprimerons sera... le premier
             * de la liste
             * et, fatalement, son suivant sera celui qui le suit
             */
            ElementListe *todel = debut;
            ElementListe *suivant = todel->suivant;
            /* nous allons maintenant travailler jusqu'à ce que l'élément qui
             * suit celui qu'on a supprimé (ou qu'on est sur le point de
             * supprimer) ne nous ramène sur le premier
            */
            do
            {
                /* pour etre propre, mettons les liens à NULL */
                todel->precedent = NULL;
                todel->suivant = NULL;
                /* et effacons l'élément */
                delete todel;
                /* l'élément suivant devient celui qui devra etre supprimé
                 */
                todel = suivant;
                /* et l'élément qui le suit devient l'élément... qui suit celui
                 * qui doit être supprimé
                 */
                suivant = todel->suivant;
            } while( suivant==debut );
        } // fin de la vérification de liste vide
        /* pour etre propre, mettons debut et fin à NULL */
        debut = NULL;
        fin = NULL;
        cout << "everything is deleted !" ;
    }
     
    Expression& Expression::insert(int val)
    {
        /* création de l'élément à rajouter */
        ElementListe *toadd = new ElementListe;
        /*initialisation des membres */
        toadd->donnee = val;
        /* l'élément qui le précède est de toutes manière le dernier de la liste */
        toadd->precedent = fin;
        /* et celui qui le suit, étant donné que nous sommes dans une
         * liste circulaire est de toutes manières le premier de la liste */
        toadd->suivant = debut;
        /* il est temps d'insérer l'élément dans la liste */
        /* S'il existe un dernier élément dans la liste, nous faisons pointer sa
         * référence "suivant" vers le nouvel élément*/
        if(fin)
            fin->suivant = toadd;
        /* S'il existe un premier élément dans la liste, nous faisons pointer sa
         * référence "precedent sur le nouvel element*/
        if(debut)
            debut->precedent = toadd;
        else
        {
            /* par contre, si la liste est vide, le nouvel élément devient le
             * premier de la liste, et ses deux références pointent vers
             * lui-même
             */
            debut = toadd;
            toadd->precedent = toadd;
            toadd->suivant = toadd;
        }
        /* quoi qu'il en soit, l'élément ajouté devient le dernier élément de
         * la liste et nous mettons le nombre d'éléments à jour
         */
        fin = toadd;
        taille++;
        /* nous pouvons maintenant renvoyer une référence sur notre liste
         * circulaire
         */
        return  *this;
    }
     
    void Expression::affiche(){
      ElementListe *courant;
      courant = this->debut;
      int i=0;
      if (!this->taille)
          cout << "la liste est vide !" << endl;
          else{
              cout << "[ " ;
              while(i<(this->taille)){
              cout << courant->donnee <<" " ;
              courant = courant->suivant;
              i++;
              }
              cout << "]" << endl;
          }
    }
    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
     
    /*******main.cpp***********/
    #include "Expression.h"
     
    int main()
    {
        Expression expr;
        expr.affiche();
     
        expr = expr.insert(5);
        expr.affiche();
     
        expr = expr.insert(2);
        expr.affiche();
     
        expr = expr.insert(1);
        expr.affiche();
     
        return 0;
    }
    ben je crois que je deviens ennuiyant maintenent !!

  7. #7
    Membre éclairé
    Avatar de Florian Goo
    Profil pro
    Inscrit en
    Septembre 2008
    Messages
    680
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Septembre 2008
    Messages : 680
    Points : 858
    Points
    858
    Par défaut
    Citation Envoyé par oswalidos Voir le message
    merci pour vos interventions et voici le probleme :
    l'utilisateur doit donner une expression , exemp : (1/7)+(2/3)+(4/3)
    Je vois, donc cette expression sera dans une chaîne.
    Il faut donc que tu joues avec les fonctions de manipulation de chaînes de std::string. Si l'expression est toujours de cette forme :
    ça devrait être faisable facilement.
    Par contre, si l'expression peut être de n'importe quelle forme, tu t'embarques dans quelque chose de très compliqué. Il te faudra une bibliothèque de parsing évoluée telle que Boost.Spirit.


    Citation Envoyé par oswalidos Voir le message
    je suis demandé de :
    -stocker les fractions dans une liste doublement chainée circulaire
    std::list est doublement chaîné, mais pas circulaire. À moins qu'on puisse configurer ça dans un argument template ?
    Autrement, un petit wrapper qui fait un modulo size(), et ni vu ni connu jt'embrouille.
    Citation Envoyé par oswalidos Voir le message
    -surcharger les opérateurs << >> < > + ()
    Pour les premiers je vois bien (tu pourras d'ailleurs ajouter -, * et /), mais pour les parenthèses je vois pas bien… quel type d'instructions tu voudrais pouvoir écrire, avec une surcharge de l'opérateur parenthèse (avec un exemple de code) ?
    J'ai comme la sensation que tu te méprends à propos de l'opérateur (). Ils agissent dans ce cas là :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    ma_classe_qui_surcharge_l_operateur_parentheses a;
    a(/*une expression*/);
    mais pas du tout dans celui-là :
    La priorité des opérateurs est codée en dur dans le langage.


    Ce que tu veux faire est faisable, mais sûrement pas aussi simplement que tu penses

  8. #8
    Membre régulier
    Homme Profil pro
    Software engineer
    Inscrit en
    Août 2008
    Messages
    139
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations professionnelles :
    Activité : Software engineer

    Informations forums :
    Inscription : Août 2008
    Messages : 139
    Points : 92
    Points
    92
    Par défaut
    En fait je ne sais pas exactement a quoi ca sert le surcharge des () mais je crois que je doit le faire , a propos de l'expression a/b , a et b se compose d'un seul chiffre donc ce ne sera pas assez compliquer ,et si vous avez jeter un coup d'oeil sur le code ,j'ai fais un bon progres .
    mais je veux savoir si un surcharge des () peux laisser le compilateur voir le (a/b) comme un objet Fraction lors de l'obtention du flux entrant !
    le compilateur detecte et comprend un entier si j'ecris :
    et avec mon travail maintenent me permet d'ecrire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    Fraction f;
    cin >> f;
    et maintenant j'ai besoin d'ecrire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    Expression expr;
    cin << expr;
    alors si le surcharge des () permet au compilateur de voir (a/b) un seul objet Fraction alors je peux recuperer les donnees facilement de l'entree standard.
    ben c'est juste une idée !
    merci encore pour vos reponses

  9. #9
    Membre régulier
    Homme Profil pro
    Software engineer
    Inscrit en
    Août 2008
    Messages
    139
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations professionnelles :
    Activité : Software engineer

    Informations forums :
    Inscription : Août 2008
    Messages : 139
    Points : 92
    Points
    92
    Par défaut
    voila l'énoncé du TD , veuillez jeter un coup d'oeil et me donner vos avis
    en tout cas merci !
    Images attachées Images attachées

  10. #10
    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
    Citation Envoyé par oswalidos Voir le message
    alors si le surcharge des () permet au compilateur de voir (a/b) un seul objet Fraction alors je peux recuperer les donnees facilement de l'entree standard.
    ben c'est juste une idée !
    Juste un petit rappel. L'opérateur (), que tu peux surcharger est un opérateur, donc une méthode. Par conséquent, il doit s'appliquer à un objet. L'écriture (a/b) est une expression ou l'opérateur / est appliqué à l'objet a avec en paramètre l'objet b. L'opérateur () n'est pas invoqué ici. L'opérateur () s'utilise plutôt comme ça : a(b).
    Quand bien même, tu avais un objet fraction à gauche de (), l'expression Fraction(a/b) sera évaluée comme suit:
    -> Evaluation de l'expression a/b
    -> Evaluation de l'opérateur() appliqué à Fraction avec comme paramètre le résultat de l'expression a/b.
    J'espère que cela éclairci un peu ton problème.

  11. #11
    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
    En relisant ton TD, je pense que la surcharge de l'opérateur () doit être utilisée pour l'évaluation de l'expression.
    En gros, je dirais:
    -> +, < et > sont surchargés sur Fraction pour l'addition et la comparaison
    -> << et >> sont surchargés pour la sérialisation des expressions. En général, cette surcharge est à l'extérieur de la classe avec un appel vers une méthode interne.
    -> () est utilisé pour l'évaluation des expressions.
    Bon courage.

Discussions similaires

  1. Problème de surcharges des Ressources
    Par rykowan dans le forum W4 Express
    Réponses: 2
    Dernier message: 05/05/2009, 21h13
  2. Réponses: 7
    Dernier message: 02/12/2007, 21h43
  3. [POO] Problème de surcharge
    Par Mr.MoOx dans le forum Langage
    Réponses: 1
    Dernier message: 14/04/2007, 19h54
  4. Réponses: 4
    Dernier message: 08/04/2007, 17h17
  5. [POO]Probléme de constructeur virtuel surchargé
    Par Laurent Dardenne dans le forum Delphi
    Réponses: 10
    Dernier message: 15/08/2006, 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