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 :

Variables polyvalentes et surcharge des opérateurs


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre émérite
    Avatar de Antoine_935
    Profil pro
    Développeur web/mobile
    Inscrit en
    Juillet 2006
    Messages
    883
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur web/mobile

    Informations forums :
    Inscription : Juillet 2006
    Messages : 883
    Par défaut Variables polyvalentes et surcharge des opérateurs
    Bonjour à tous.

    Dans le cadre de mon project CWS (langage interprété), je dois créer une classe de variables supportant les types de variables majeures.

    Pour simplifier la suite de l'écriture du code, j'utilise la surcharge des opérateurs
    Voici à quoi ressemble la structure de la classe:
    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
     
    class cwsVar {
        public:
            friend ostream &operator<<(ostream &, cwsVar &);
     
            cwsVar();
            cwsVar(cwsVar &);
            // should create constructors with different types (int, float, bool & string)
            int getIntVal();
    //        float getFloatVal();
    //        bool getBoolVal();
    //        string getStringVal();
            int getType();
            // on getVal, switch type, and return value formatted to wanted type
     
            // should first make +, -, / and * operators, and then apply it to +=... with *this = value1 + value2
     
            cwsVar &operator=(int);
            cwsVar &operator+(int);
            cwsVar &operator-(int);
            cwsVar &operator*(int);
            cwsVar &operator/(int);
            cwsVar &operator+=(int);
            cwsVar &operator-=(int);
            cwsVar &operator*=(int);
            cwsVar &operator/=(int);
            // also to do for cwsVar, float, bool and string... something easier ?
        private:
            int intVal;
            float floatVal;
            bool boolVal;
            string stringVal;
            int currentType;
    };
    Là où je bloque, c'est que, parti comme ca, je suis bon pour me taper tous les opérateurs pour tous les types (cwsVar, int, float, bool, string).

    N'y a-t-il pas une solution plus simple, avec des templates par exemple ? Pourrait-on imaginer avoir une seulement variable de contenu (remplacant intVal, floatVal etc...) avec un template ainsi que des méthode template ?
    Sachant qu'une fois la classe terminée, je dois pouvoir faire des opérations simple, comme
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    	cwsVar myVar;
    	myVar = 5;
    	cout << myVar.getIntVal() << endl;
    	myVar += 10;
    	cout << myVar.getIntVal() << endl;
    	myVar -= 7;
    	cout << myVar.getIntVal() << endl;
    	myVar /= 2;
    	cout << myVar.getIntVal() << endl;
    	cout << "Size of cwsVar: " << sizeof(myVar) << endl;
    	cout << (myVar + 5) << endl;
    	cwsVar anotherVar = myVar;
    	cout << anotherVar << endl;

  2. #2
    Membre chevronné
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    258
    Détails du profil
    Informations personnelles :
    Âge : 46
    Localisation : France, Bas Rhin (Alsace)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 258
    Par défaut
    Regarde du cote de boost::any pour stocker ta valeur. Les operateurs peuvent alors etre definis par
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
      template<typename T>
      cwsVar & cwsVar::operator+=(T rhs)
      {
        T nativeValue = boost::any_cast<T>(value_);
        nativeValue += rhs;
        value_ = nativeValue;
      }
    ou value_ est le membre de ta classe de type boost::any

  3. #3
    Membre émérite
    Avatar de Antoine_935
    Profil pro
    Développeur web/mobile
    Inscrit en
    Juillet 2006
    Messages
    883
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur web/mobile

    Informations forums :
    Inscription : Juillet 2006
    Messages : 883
    Par défaut
    Merci de ta réponse


    Mais, n'ayant jamais utilisé les templates, j'avoue avoir un peu de mal à comprendre le code. Saurais-tu expliquer ca en bref, ou je ferais mieux de trouver une doc complète sur les templates ? (ce que je fais d'ailleurs à l'instant)

    En réalité, je cherche également à me passer de bibliothèques extérieures (sauf la STL bien sur.)

  4. #4
    Membre chevronné
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    258
    Détails du profil
    Informations personnelles :
    Âge : 46
    Localisation : France, Bas Rhin (Alsace)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 258
    Par défaut
    Jette un oeil a la FAQ sur les templates : http://c.developpez.com/faq/cpp/?page=templates.

    Ce que je propose c'est un operator+= qui prend un type T (quelconque) en parametre, et qui va l'ajouter a ta valeur. Lorsque cet operateur est appele, la valeur stockee dans le boost::any est transformee en un objet de type T et l'operateur += du type T est appele.

    Tout marche bien tant que ton type T avec lequel tu appelle cet operateur dispose d'un operateur +=. Si ce n'est pas le cas, tu auras une erreur de compilation disant qu'il n'est pas possible d'instancier la fonction.

    Quant a se passer de bibliotheques exterieures, c'est un noble objectif, mais qui revient dans ce cas precis a reinventer une partie de la roue (ici boost::any, ou quelque chose de similaire). C'est un bon exercice, mais pour un projet serieux c'est surtout une perte de temps, vu que tu vas devoir concevoir, coder, tester et debugger des parties supplementaires.

  5. #5
    Membre émérite
    Avatar de Antoine_935
    Profil pro
    Développeur web/mobile
    Inscrit en
    Juillet 2006
    Messages
    883
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur web/mobile

    Informations forums :
    Inscription : Juillet 2006
    Messages : 883
    Par défaut
    Pas besoin enréalité de réinventer la roue.
    J'ai trouvé un système plus simple.

    Par contre, c'est la première fois que je fais de la surcharge et je tombe sur des bugs que je ne m'explique pas...

    Je joins le fichier executable dans un zip pour vous donner la sortie de debug.

    Vous pouvez voir que quand j'additionne var1 et var2, il y a une erreur de calcul que je ne comprends pas. var1 + var2 devrait donner 6, et non un chiffre aberrant.

    Je ne comprends pas pourquoi.

    Voici deux fonctions qui pourraient être en cause, ainsi que la définition de la classe et le main()

    Quelqu'un a une idée de mon erreur ?
    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
    class cwsVar {
        public:
            friend ostream &operator<<(ostream &, const cwsVar &);
     
            cwsVar();
            cwsVar(const cwsVar &);
            cwsVar(int);
            cwsVar(float);
            cwsVar(double);
            cwsVar(bool);
            cwsVar(string);
            cwsVar(const char *);
            int getIntVal();
            float getFloatVal();
            bool getBoolVal();
            string getStringVal();
            int getType();
            cwsVar &operator+(cwsVar &);
            cwsVar &operator-(cwsVar);
            // Encore à implémenter
            /*cwsVar &operator+(cwsVar);
            cwsVar &operator-(cwsVar);
            cwsVar &operator*(cwsVar);
            cwsVar &operator/(cwsVar);
            cwsVar &operator+=(cwsVar);
            cwsVar &operator-=(cwsVar);
            cwsVar &operator*=(cwsVar);
            cwsVar &operator/=(cwsVar);*/
     
            // no : put a creator for each type, but operators only for cwsVar types
            // and then only make operations with cwsVar objects
        private:
            int intVal;
            double floatVal;
            bool boolVal;
            string stringVal;
            int currentType;
    };
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    cwsVar &cwsVar::operator+(cwsVar &value) {
        cwsVar result;
        switch(this->currentType) {
            case TYPE_INT: result = this->intVal + value.intVal; break;
            case TYPE_FLOAT: result = this->floatVal + value.floatVal; break;
            case TYPE_BOOL: break; //throw operationNotPermittedError();
            case TYPE_STRING: result = this->stringVal + value.stringVal; break;
        }
        cout << result.getIntVal() << endl;
        return result;
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    ostream &operator<<(ostream &stream, const cwsVar &var) {
        switch(var.currentType) {
            case TYPE_INT: stream << "TYPE_INT : " << var.intVal; break;
            case TYPE_FLOAT: stream << "TYPE_FLOAT : " << var.floatVal; break;
            case TYPE_BOOL: stream << "TYPE_BOOL : " << var.boolVal; break;
            case TYPE_STRING: stream << "TYPE_STRING : " << var.stringVal; break;
        }
        return stream;
    }
    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
     
    int main(int arc, char **argv) {
    	// fileRenderer renderer = new fileRenderer(argv[1]); // initializes the firts filerenderer with argv[1]
    	// this will be the final step
    	// tests will be made before
        cwsVar var1(4);
        cout << "var1 : " << var1 << endl;
        cwsVar var2("Hello World !");
        cout << "var2 : " << var2 << endl;
        var2 = 2;
        cout << "var2 : " << var2 << endl;
        cwsVar var3(var1 + var2);
        cout << "var1 + var2 : " << (var1 + var2) << endl;
        cout << "var2 + var1 : " << (var2 + var1) << endl;
        cout << "(var1 + var2).getIntVal() : " << (var1 + var2).getIntVal() << endl;
        cout << "var3 : " << var3 << endl;
    	return 0;
    }
    Fichiers attachés Fichiers attachés
    • Type de fichier : zip cws.zip (133,4 Ko, 83 affichages)

  6. #6
    Membre émérite
    Avatar de Antoine_935
    Profil pro
    Développeur web/mobile
    Inscrit en
    Juillet 2006
    Messages
    883
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur web/mobile

    Informations forums :
    Inscription : Juillet 2006
    Messages : 883
    Par défaut
    Allelouiha !
    Eurêka.

    à la plac de ca:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    cwsVar &operator+(cwsVar &);
    je devais mettre ca:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    cwsVar operator+(cwsVar);

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

Discussions similaires

  1. polymorphisme et surcharge des opérateurs
    Par j.david dans le forum Langages de programmation
    Réponses: 1
    Dernier message: 02/01/2011, 19h17
  2. surcharge des opérateurs
    Par Arson dans le forum C++
    Réponses: 9
    Dernier message: 30/05/2008, 11h40
  3. Réponses: 2
    Dernier message: 11/01/2008, 10h40
  4. Réponses: 7
    Dernier message: 02/12/2007, 21h43
  5. Surcharge des opérateurs ?
    Par kedare dans le forum Ruby
    Réponses: 3
    Dernier message: 06/11/2006, 23h47

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