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

Langage C++ Discussion :

Surcharge de l'opérateur + qui ne marche que dans un sens


Sujet :

Langage C++

  1. #1
    Futur Membre du Club
    Profil pro
    Inscrit en
    Mars 2011
    Messages
    13
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2011
    Messages : 13
    Points : 5
    Points
    5
    Par défaut Surcharge de l'opérateur + qui ne marche que dans un sens
    Bonjour,

    J'ai développé une classe de chaine dynamique assez complète, il y a des années. La compilation et l'utilisation se passaient très bien jusqu'à ce que je mette à jour mon compilateur (g++). Je ne me suis pas mis à la page, mais le changement des normes C++ me fait aujourd'hui un résultat que je ne comprends pas :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    Dynachar d("bonjour");
     
    d=d+" Monsieur";
     
    cout<<d<<endl;
    Là, ça marche très bien, ça m'affiche "bonjour Monsieur".

    Mais si je fais cela (en inversant le sens) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    Dynachar d("bonjour");
     
    d=d+" Monsieur";
     
    d="Ah, " + d;
     
    cout<<d<<endl;
    Ca ne compile pas :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    test.C: In function 'int main(int, char**)':
    test.C:20: error: ambiguous overload for 'operator+' in '"Ah, " + d'
    ../lib/Dynachar.h:1488: note: candidates are: Dynachar operator+(const char*, Dynachar&)
    ../lib/Dynachar.h:1501: note:                 Dynachar operator+(const char*, Dynachar)
    Voici mes prototypes liés à l'exemple ci-dessus :

    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
    Dynachar operator + (Dynachar &);                            //ajoute 2 Dynachar (et retourne 1 Dynachar)
     
       Dynachar operator + (Dynachar);                              //ajoute 2 Dynachar (et retourne 1 Dynachar)
     
       Dynachar operator + (const char *);                          //idem mais entre 1 Dynachar et 1 chaine
     
       friend ostream &operator <<(ostream&,const Dynachar&);       //permet de faire un << avec un Dynachar
     
       friend istream &operator >>(istream&,Dynachar&);             //permet de faire un >> avec un Dynachar
     
    };
     
       Dynachar operator + (const char *,Dynachar &);               //fonction ext. à la classe. Ret. 1 Dynachar
     
       Dynachar operator + (const char *,Dynachar);                 //fonction ext. à la classe. Ret. 1 Dynachar
    J'ai vu des solutions approchantes qui consistait à forcer un cast, mais je ne suis pas parvenu à les mettre en oeuvre.

    Merci de votre aide !

    Jérôme.

  2. #2
    Membre actif
    Homme Profil pro
    Consultant BigData
    Inscrit en
    Juillet 2009
    Messages
    129
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Consultant BigData

    Informations forums :
    Inscription : Juillet 2009
    Messages : 129
    Points : 280
    Points
    280
    Par défaut
    Lorsque tu écris :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    Dynachar d("bonjour");
    d=d+" Monsieur";
    Tu appliques l'opérateur "+" d'un Dynachar prenant en argument une chaine de caractère.

    Lorsque tu écris :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    Dynachar d("bonjour");
    d="Ah, " + d;
    Tu appliques l'opérateur "+" d'une chaine de caractère prenant en argument un Dynachar.
    Je pense, à juste titre, que cet opérateur n'existe pas

    Une solution serait de pouvoir transformer ta chaine "Ah, " en Dynachar et d'appliquer l'opérateur "+" entre deux Dynachar

  3. #3
    Membre averti
    Homme Profil pro
    Analyse système
    Inscrit en
    Novembre 2008
    Messages
    227
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Analyse système
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Novembre 2008
    Messages : 227
    Points : 311
    Points
    311
    Par défaut
    Pour moi il faut que tu définisses un operator + en dehors de ta classe et qui prend un char et un Dynachar

  4. #4
    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
    Salut,
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    void fonction(int ){} // 1
    void fonction(int &){} // 2
    int main()
    {
        int i;
        fonction(i);
     
        return 0;
    }
    provoque la même erreur. Pourquoi ? Sur quel critère le compilateur peut-il différencier 1 ou 2 ? Aucun. D'où cette erreur.

    Ma question : pourquoi avais-tu ces deux surcharges?? Pourquoi n'avais-tu pas uniquement :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Dynachar operator + (const char *,Dynachar const &);
    Idem dans la classe :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Dynachar operator + (Dynachar &);
       Dynachar operator + (Dynachar);
    devraient être supprimées pour avoir uniquement :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Dynachar operator + (Dynachar const &) const;
    Et comme on tend à privilégier les opérateurs à partir de leur forme +=, ta classe devrait ressembler à :
    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
    class dynachar
    {
      public:
      explicit dynachar(char const*);
      dynachar();
     
      // une politique de copie si tu as une allocation:
      dynachar(dynachar const &);
      dynachar& operator=(dynachar const&);
     
      // destruction si tu as une allocation
      ~dynachar();
     
     
      dynachar& operator+=(dynachar const&);
     
    };
     
    dynachar operator+(dynachar const &lhs_, dynachar const &rhs_)
    {
     
        return dynachar(lhs_)+=rhs_;
    }
     
    dynachar operator+(char const *lhs_, dynachar const &rhs_)
    {
     
        return dynachar(lhs_)+=rhs_;
    }
     
    dynachar operator+(dynachar const &lhs_, char const *rhs_)
    {
     
        return dynachar(lhs_)+=dynachar(rhs_);
    }
    On peut éventuellement chipoter sur le passage par référence relativement à la (N)RVO.

    Ou encore mieux à
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    typedef std::string dynachar;

  5. #5
    Membre chevronné
    Avatar de Goten
    Profil pro
    Inscrit en
    Juillet 2008
    Messages
    1 580
    Détails du profil
    Informations personnelles :
    Âge : 33
    Localisation : France

    Informations forums :
    Inscription : Juillet 2008
    Messages : 1 580
    Points : 2 205
    Points
    2 205
    Par défaut
    Ou profiter de la symmétrie et :
    dynachar operator+(dynachar const &lhs_, dynachar const &rhs_)

    (mais faut enlever le explicit)
    "Hardcoded types are to generic code what magic constants are to regular code." --A. Alexandrescu

  6. #6
    Futur Membre du Club
    Profil pro
    Inscrit en
    Mars 2011
    Messages
    13
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2011
    Messages : 13
    Points : 5
    Points
    5
    Par défaut
    Merci à tous pour vos différentes pistes qui m'ont conduit à modifier mon code.

    A vrai dire, je ne sais plus pourquoi, à l'époque, j'avais défini une surcharge par recopie et une surcharge par référence. Pour avoir le Dynachar à droite du "+", c'était bien défini à l'extérieur de la classe.

    La classe est assez grosse et comporte pas mal de fonctions, donc il y a bien le code nécessaire, constructeurs et destructeur par exemple.

    J'ai commenté dans ma classe la ligne suivante :

    //Dynachar operator + (const char *,Dynachar); //fonction ext. à la classe. Ret. 1 Dynachar

    Ainsi que le code associé.

    Et du coup, ça compile bien, et ça m'affiche bien :"Ah, bonjour Monsieur".

    Si je comprends bien, il ne fallait pas avoir de surcharge par recopie (ça compilait bien avant pourtant).

    J'ai du coup le même problème quand j'associe 2 Dynachar avec un "+" :

    ../lib/Dynachar.h:1456: note: candidates are: Dynachar Dynachar::operator+(Dynachar&)
    ../lib/Dynachar.h:1466: note: Dynachar Dynachar::operator+(Dynachar)

    Je pense également commenter la fonction par recopie. Pourtant, il me semblait que si je faisais :

    cout<<Dynachar("Bonjour") + " Monsieur<<endl;

    ça utilisait une recopie, et non une référence, mais en fait ça marche très bien, ça compile et ça me met "Bonjour Monsieur". Ca doit donc bien utiliser une référence qui n'est accessible qu'une fois et détruite à la fin du programme seulement (Dynachar("Bonjour") n'étant pas déclaré dans une variable, donc pas accessible. Peut-être est-il détruit juste après, je ne sais pas).

    A part mes lacunes dans ce domaine, je pense que je peux passer le sujet en résolu, sauf si quelqu'un veut apporter une précision. Merci à tous en tout cas.

    Jérôme.

  7. #7
    Membre chevronné
    Avatar de Joel F
    Homme Profil pro
    Chercheur en informatique
    Inscrit en
    Septembre 2002
    Messages
    918
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Chercheur en informatique
    Secteur : Service public

    Informations forums :
    Inscription : Septembre 2002
    Messages : 918
    Points : 1 921
    Points
    1 921
    Par défaut
    l'operator+ prends ses arguments par referenec constantes.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    DYnachar operator+( Dynachar const& );

    ensuite, il est preconisé de n'avoir en fonction membre les operateurs +=, etc ... et de reecrire + de maniere externe et symmetrique:


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    DynaChar operator+(DynaChar const& a, DynaChar const& b)
    {
       DynaChar that(a);
       that += b;
       return that;
    }
    Ca evite duplication et erreur.

    sinon std::string + les boost::stringalgo :o

  8. #8
    Membre éprouvé Avatar de oxyde356
    Homme Profil pro
    Ingénieur Recherche Imagerie
    Inscrit en
    Février 2006
    Messages
    797
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur Recherche Imagerie

    Informations forums :
    Inscription : Février 2006
    Messages : 797
    Points : 1 087
    Points
    1 087
    Par défaut
    Citation Envoyé par 3DArchi Voir le message
    Ou encore mieux à
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    typedef std::string dynachar;
    Lol j'y est pensé à celle là en lisant le code mais elle est méchante Archi

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

Discussions similaires

  1. Script Fade In qui ne marche que sur IE
    Par TMattio dans le forum Général JavaScript
    Réponses: 4
    Dernier message: 26/08/2010, 14h16
  2. DataBinding ne marche que dans un sens avec un canvas
    Par Harry_polin dans le forum Windows Presentation Foundation
    Réponses: 13
    Dernier message: 19/01/2010, 12h19
  3. Réponses: 10
    Dernier message: 17/01/2010, 20h58
  4. [RegEx] REGEX qui ne marche que dans certains cas
    Par Galdon dans le forum Langage
    Réponses: 4
    Dernier message: 14/01/2010, 09h15
  5. CSS input qui ne marche que sur Firefox
    Par DJ Caësar 9114 dans le forum Mise en page CSS
    Réponses: 4
    Dernier message: 24/04/2009, 09h41

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