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 opérateur operator<< et type enum


Sujet :

C++

  1. #1
    maximesav1
    Invité(e)
    Par défaut Surcharge opérateur operator<< et type enum
    Bonjour !

    Je galère pas mal sur l'exercice suivant, je n'ai pas vocation à devenir programmeur mais un concours de circonstance m'oblige à réaliser une formation en ligne... En bref !
    Voici le code suffisant (compilable via http://coliru.stacked-crooked.com/ )

    Je ne peux modifier qu'entre les bornes "commencer et finissez votre code ici".
    L'affichage n'est pas correct
    bateau pirate en (0, 0) battant pavillon 0, 0 devrait être
    bateau pirate en (0, 0) battant pavillon pirate, intact

    Donc les surchargeurs Pavillon et Etat sont inopérantes. Et même celle coordonnées d'ailleurs..

    Je pense que la solution est assez "simple" pour des professionnels, mais pour moi, je sèche.

    Merci infiniment à ceux qui tenteront de résoudre cet affichage
    Dernière modification par maximesav1 ; 22/07/2016 à 11h33.

  2. #2
    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 705
    Points
    2 705
    Par défaut
    Les enums sont des entiers. Quand tu les envoies à un flux, ils sont donc affichés sous cette forme.
    Si tu veux les afficher sous forme de chaîne, il te faut créer des maps qui à tes valeurs d'enum associe des chaînes.

  3. #3
    maximesav1
    Invité(e)
    Par défaut
    En gardant en tête la contrainte qui est de ne pouvoir modifier le code qu'entre les bornes
    /*****************************************************
    * Compléter le code à partir d'ici
    *****************************************************/

    Comment faire cela ?

    il y aurait une syntaxe pour le pavillon_ genre pavillon_.tostring... ? (je fabule)

    sinon et je penche plus vers cette solution, le mapping via un surchargeur comme celui ci ? ça mappe bien le jollyrogers au string pirate, non?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    ostream & operator<<(ostream& aff, Pavillon const& p) {
        switch(p) {
        case Pavillon::JollyRogers: aff << "pirate"; break;
    	case Pavillon::CompagnieDuSenegal: aff << "français"; break;
    	case Pavillon::CompagnieDOstende: aff << "autrichien"; break;
    	default: aff << "pavillon inconnu"; }
    	return aff;
    }
    Dernière modification par Bousk ; 22/07/2016 à 09h11.

  4. #4
    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 967
    Points
    32 967
    Billets dans le blog
    4
    Par défaut
    Non pas de tostring ni quoi que ce soit qui te donne le nom de l'enum.
    Si vraiment j'ai besoin de faire quelque chose comme ça, j'utilise des macros du style
    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
    // enum.h
    BEGIN_ENUM(Dude)
    ENUM_VALUE(Toto)
    ENUM_VALUE(Tata)
    END_ENUM()
     
    // enum.cpp
    #define BEGIN_ENUM(n) enum class n {
    #define ENUM_VALUE(v) v,
    #define END_ENUM() };
    #include "enum.h"
    #undef BEGIN_ENUM
    #undef ENUM_VALUE
    #undef END_ENUM
     
    #define BEGIN_ENUM(n) const char* ToString(n val) { \
    switch(val) {
    #define ENUM_VALUE(v) case v: return #v;
    #define END_ENUM() default: return "<unknown>"; }
    #include "enum.h"
    #undef BEGIN_ENUM
    #undef ENUM_VALUE
    #undef END_ENUM
    aux erreurs près, c'est l'idée
    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.

  5. #5
    maximesav1
    Invité(e)
    Par défaut
    Merci pour l'intérêt que tu portes à mes questions Bousk.

    Ceci dit, dans l'exercice qu'on m'impose, je dois composer avec cet unique fichier (pas de .h donc) et dans les bornes délimitées (commencer ici le code, finir ici le code) et ne pas le dépasser puisqu'un robot le corrige)... En conséquence, ta solution est impossible à réaliser, à moins que je n'ai tout simplement pas compris ce que tu proposes !
    Ce qui est sûr, c'est que
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    virtual ostream & afficher(ostream & aff) const{
            aff << " en (" << position_.x() << ", " << position_.y() << ") battant pavillon " << pavillon_ << ", " << etat_;
            return aff;
        }
    Je dois peut-être modifier cela aussi. en l'état, tu m'informes que pavillon_ et etat_ sont des entiers.
    Mon énoncé

    Dans la partie autorisée, après le commentaire
    /*****************************************************
    * Compléter le code à partir d’ici
    *****************************************************/
    et après l’accolade fermant la classe Navire, commencez par développer les
    éléments suivants :
    — l’opérateur += pour la classe Coordonnees (...)
    — définition d’une fonction distance (...)
    — surcharge de l’opérateur d’affichage << pour les Coordonnees ; le format
    d’affichage à respecter est le suivant : « (<x>, <y>) », où <x>
    est la valeur de la première coordonnée et <y> celle de la seconde ; par
    exemple :
    (1, 2)
    — surcharge de l’opérateur d’affichage << pour les Pavillons, qui affichera
    :
    — "pirate" pour la valeur JollyRogers ;
    — "français" pour la valeur CompagnieDuSenegal ;
    — "autrichien" pour la valeur CompagnieDOstende (Ostende
    est bien en Belgique de nos jours, mais à l’époque elle était sous occupation
    autrichienne !) ;
    — et "pavillon inconnu" dans les autres cas ;
    — surcharge de l’opérateur d’affichage << pour les Etats, qui affichera :
    — "intact" pour la valeur Intact ;
    — "ayant subi des dommages" pour la valeur Endommage ;
    — "coulé" pour la valeur Coule ;
    — et "état inconnu" dans les autres cas.

  6. #6
    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 967
    Points
    32 967
    Billets dans le blog
    4
    Par défaut
    Si c'est juste pour faire plaisir à ton prof et n'as que peu de valeurs alors utilise une std::map, ou une fonction avec un switch, et basta
    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.

  7. #7
    Membre averti Avatar de RPGamer
    Homme Profil pro
    Ingénieur en systèmes embarqués
    Inscrit en
    Mars 2010
    Messages
    168
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : Suisse

    Informations professionnelles :
    Activité : Ingénieur en systèmes embarqués

    Informations forums :
    Inscription : Mars 2010
    Messages : 168
    Points : 395
    Points
    395
    Par défaut
    Une solution à base de std::map pourrait convenir en effet. Par exemple quelque chose comme:

    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
    #include <iostream>
    #include <string>
    #include <map>
     
    enum MyEnum
    {
        VALUE1,
        VALUE2,
        VALUE3
    };
     
    std::map<MyEnum, std::string> myEnumValues =
    {
        {VALUE1, "value1"},
        {VALUE2, "value2"},
        {VALUE3, "value3"}
    };
     
    std::ostream &operator <<(std::ostream &os, MyEnum val)
    {
        if (myEnumValues.find(val) == myEnumValues.end())
        {
            return os << "unknown value";
        }
     
        return os << myEnumValues[val];
    }
     
    int main()
    {
        std::cout << VALUE3 << std::endl;
    }

  8. #8
    maximesav1
    Invité(e)
    Par défaut
    Impossible d'ajouter l'include map :'(
    C'est une formation en ligne, c'est bridé de chez bridé, je pète un câble.

    J'essaye la méthode bidon avec les switchs mais je pense pas que ça sera accepté.. L'idéal serait de corriger mes opérateurs<< je pense que c'est ça qui est attendu

  9. #9
    Membre averti Avatar de RPGamer
    Homme Profil pro
    Ingénieur en systèmes embarqués
    Inscrit en
    Mars 2010
    Messages
    168
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : Suisse

    Informations professionnelles :
    Activité : Ingénieur en systèmes embarqués

    Informations forums :
    Inscription : Mars 2010
    Messages : 168
    Points : 395
    Points
    395
    Par défaut
    Dans ce cas oui, la solution basée sur un switch est la seule qui prévaut.

    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
    std::ostream &operator <<(std::ostream &os, MyEnum val)
    {
        switch (val)
        {
            case VALUE1:
            return os << "value1";
     
            case VALUE2:
            return os << "value2";
     
            case VALUE3:
            return os << "value3";
     
            default:
            return os << "unknown value";
        }
    }

  10. #10
    maximesav1
    Invité(e)
    Par défaut
    Dans mon cas, quand je l'applique :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    ostream & operator<<(ostream& os, Pavillon val) {
        switch(val) {
        case 0: return os << "pirate";
        case Pavillon::CompagnieDuSenegal: return os << "français";
    	case Pavillon::CompagnieDOstende: return os << "autrichien";
    	default: return os << "inconnu"; }
    }
    Que je mette les entiers (0, 1, 2), les Pavillon::nomcomplet ou rien (voir default) il continue de me mettre les entiers, j'arrive pas à lui faire "voir" mon surchargeur.

    Sinon en faisant de façon sale

    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
       virtual ostream & afficher(ostream & aff) const{   
            //string p;
            string e;
            //switch(pavillon_) {
            //case 0 : p =  "pirate"; break;
            //case 1 : p = "français"; break;
            //case 2 : p = "autrichien"; break;
            //default: p = "pavillon inconnu"; }
            switch(etat_) {
            case 0 : e = "intact"; break;
            case 1 : e = "ayant subi des dommages"; break;
            case 2 : e = "coulé"; break;
            default: e = "état inconnu"; }
        aff << " en (" << position_.x() << ", " << position_.y() << ") battant pavillon " << pavillon_ << ", " << e;
            return aff;
        }
    ça fonctionne. Cependant le robot de correction me donne cette sortie... (dans le cas ou j'utilise uniquement la solution sale)
    erreur dans "test_basic_ops": ERR3: Etat::operator<< n'est pas correct. J'attendais : « intact » alors que votre programme a écrit : « 0 » erreur dans "test_basic_ops": ERR3: Etat::operator<< n'est pas correct. J'attendais : « ayant subi des dommages » alors que votre programme a écrit : « 1 »
    Alors que ma sortie est parfaite (pas d'entier, juste les bons mots. Est-ce que le correcteur irait chercher quelque part avant l'affichage ?) Bien sûr je n'y ai pas accès :p

    C'est corrigé. Merci à tous
    Dernière modification par maximesav1 ; 22/07/2016 à 11h32.

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

Discussions similaires

  1. type enum
    Par donny dans le forum PostgreSQL
    Réponses: 2
    Dernier message: 17/05/2005, 14h05
  2. Surcharge opérateurs
    Par ghostdogpr dans le forum C++
    Réponses: 5
    Dernier message: 18/03/2005, 11h51
  3. 1 champ de type enum à 3 valeurs ou 2 champs booléens ?
    Par El Saigneur dans le forum Décisions SGBD
    Réponses: 3
    Dernier message: 22/01/2005, 08h53
  4. [VB.NET] Variable de type enum avec du string
    Par Mouse dans le forum Windows Forms
    Réponses: 4
    Dernier message: 13/01/2005, 18h22
  5. [MySQL] Valeur par défaut d'un type ENUM
    Par aliasjcdenton dans le forum PHP & Base de données
    Réponses: 2
    Dernier message: 31/10/2004, 20h44

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