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] Type de retour


Sujet :

C++

  1. #1
    Membre régulier

    Inscrit en
    Juin 2008
    Messages
    49
    Détails du profil
    Informations forums :
    Inscription : Juin 2008
    Messages : 49
    Points : 114
    Points
    114
    Par défaut [Surcharge d'opérateurs] Type de retour
    Bonjour tout le monde !

    J'ai une question qui me dérange depuis longtemps et que de multiples essais n'ont pas réussi à solutionner.
    Quel doit être le type de retour d'un opérateur surchargé ?

    Prenons par exemple une classe vecteur et son opérateur +=.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Vecteur& Vecteur::operator+=(const Vecteur& v);
    La référence retournée doit-elle être constante ou pas ?

    De même pour les opérateurs renvoyant une valeur, doit-elle être constante ou pas ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Vecteur operator+(const Vecteur& v,const Vecteur& w);
    D'après GoTW, les retours doivent être const, d'après les exemples de la FAQ, il n'y a pas de const, et c'est comme cela pour toutes les sources; on trouve les deux avis.
    Personellement, j'ai jamais mis de const, mais je ne suis pas convaincu de cette approche.

    Merci à vous.

  2. #2
    Membre averti
    Homme Profil pro
    Game Graphics Programmer
    Inscrit en
    Août 2006
    Messages
    408
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Allemagne

    Informations professionnelles :
    Activité : Game Graphics Programmer
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Août 2006
    Messages : 408
    Points : 392
    Points
    392
    Par défaut
    Refléchis une seconde à ce que tu veux obtenir:
    l'operator+= prends une variable à ajouter qu'il n a pas à modifier (et qui peut être constante) et retourne une référence sur lui-même dont il se peut que veuilles encore modifier des choses.
    Donc le chemin le plus sûr, c'est type& operator+=(const type& rhv); .
    Pour l'opérateur + global, regarde du côté de Boost.operator pour voir ce qu'il te permet d'obtenir.

    Exemple, un vec4(x,y,z,w):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    vec4& vec4::operator+=(const vec4& rhv)
    { /* somme */ return *this; }
    maintenant, prenons l'exemple suivant:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    vec4 a(des valeurs);
    vec4 b(autres valeurs);
     
    //et on veut faire l'addition et enchaîner direct sur un membre.
    (a += b).y = b.z;
    cela revient à a += b; et a.y = b.z;
    c'est pas recommandé, certes, mais ca se peut.

    J'espère que ca t'a aidé.

  3. #3
    Membre régulier

    Inscrit en
    Juin 2008
    Messages
    49
    Détails du profil
    Informations forums :
    Inscription : Juin 2008
    Messages : 49
    Points : 114
    Points
    114
    Par défaut
    Oui, c'est justement ce à quoi je pensais. Le type de retour peut être utilisé comme rvalue pour une autre opération (même si c'est pas du meilleur style). C'est pourquoi j'ai toujours mis le type de retour non-constant.

    Mais si je prends par exemple cette classe de boost: http://www.boost.org/doc/libs/1_37_0/boost/rational.hpp , l'opérateur ++ a pour signature :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    const rational& operator++();
    Avec un const. Pourquoi ?

    De même dans ce code tiré de GOTW (http://www.gotw.ca/gotw/006.htm) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
       const Polygon operator+( const Polygon& lhs,
                                 const Polygon& rhs ) {
            Polygon ret = lhs;
            const int last = rhs.GetNumPoints();
            for( int i = 0; i < last; ++i ) // concatenate
                ret.AddPoint( rhs.GetPoint(i) );
            return ret;
        }
    Je pense que les gens qui ont écrits ces codes savent ce qu'ils font et qu'il y a sûrement une raison à ces "const". Mais je ne vois pas à part empêcher justement certains trucs moches en chaînant des opérations, mais dans ce cas, pourquoi tous les opérateurs n'ont-ils pas un type de retour constant ?

  4. #4
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 614
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 614
    Points : 30 626
    Points
    30 626
    Par défaut
    Salut,

    Le cas du polygone est intéressant parce qu'il s'agit d'un objet que l'on pourrait qualifier "d'atomique"...

    Si tu le modifie d'une quelconque manière (en déplaçant l'un de ses angles, ou en modifiant le nombre de côtés dont il est fait), tu obtient littéralement "un autre" polygone.

    Il est donc "normal" de considérer qu'un polygone doive... rester constant

    La seule optique qui reste "cohérente" est alors de se dire que, si tu additionne deux polygone, tu en crée un troisième qui... n'a rien à voir avec les deux autres, et qui ne pourra pas non plus être modifié.

    Dans d'autres cas, il peut être "cohérent" d'estimer qu'un objet puisse être modifié, sans *forcément* obtenir un nouvel objet, et, dans ce cas, il peut être non constants
    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

  5. #5
    Expert confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Décembre 2003
    Messages
    3 549
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Décembre 2003
    Messages : 3 549
    Points : 4 625
    Points
    4 625
    Par défaut
    Ça sert à ne pas pouvoir faire
    a + b = c;
    Boost ftw

  6. #6
    Membre régulier

    Inscrit en
    Juin 2008
    Messages
    49
    Détails du profil
    Informations forums :
    Inscription : Juin 2008
    Messages : 49
    Points : 114
    Points
    114
    Par défaut
    Ok. Mais pour les nombres rationnels, comment interpréter la constance du type retourné ?

    Peut-on dégager une "règle" générale ?

  7. #7
    Expert confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Décembre 2003
    Messages
    3 549
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Décembre 2003
    Messages : 3 549
    Points : 4 625
    Points
    4 625
    Par défaut
    La constance du type retourné sert à ce que ce que j'ai écrit plus haut ne compile pas, parce que sinon ça marche.
    Boost ftw

  8. #8
    Membre émérite
    Avatar de white_tentacle
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    1 505
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 1 505
    Points : 2 799
    Points
    2 799
    Par défaut
    En général, il vaut mieux renvoyer un const, puisque modifier le résultat de l'opération est bizarre le plus souvent.

    Il y a aussi des exceptions : operator= doit renvoyer un non const pour un smart pointer (pas possible autrement).

    Une bonne pratique, c'est que l'objet a le même comportement qu'un type standard (int par exemple). C'est relativement intuitif, du coup.

  9. #9
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    Il ne faut pas oublier que sur un compilateur conforme (à savoir: autre que Visual), une fonction prenant une référence non-const en paramètre ne peut pas modifier un temporaire non-nommé, donc le (a+b)=c ne compilera pas, const ou pas const...
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  10. #10
    Membre régulier

    Inscrit en
    Juin 2008
    Messages
    49
    Détails du profil
    Informations forums :
    Inscription : Juin 2008
    Messages : 49
    Points : 114
    Points
    114
    Par défaut
    Citation Envoyé par loufoque Voir le message
    La constance du type retourné sert à ce que ce que j'ai écrit plus haut ne compile pas, parce que sinon ça marche.
    Mouais. Mais alors pourquoi d'autres opérateurs ne renvoient pas d'objets constants ?

  11. #11
    Membre à l'essai
    Profil pro
    Inscrit en
    Septembre 2008
    Messages
    17
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2008
    Messages : 17
    Points : 19
    Points
    19
    Par défaut
    Citation Envoyé par loufoque Voir le message
    Ça sert à ne pas pouvoir faire
    a + b = c;
    En effet ^^

Discussions similaires

  1. surcharge operator[] problème type retour
    Par -Gesicht- dans le forum C++
    Réponses: 9
    Dernier message: 13/06/2013, 01h04
  2. surcharge d'opérateurs du type "var[31:0]"
    Par frederic_dumoulin dans le forum Ruby
    Réponses: 3
    Dernier message: 09/02/2012, 09h13
  3. Réponses: 4
    Dernier message: 17/02/2011, 16h39
  4. Type de retour des surcharges d'opérateur
    Par syl1405 dans le forum C++
    Réponses: 8
    Dernier message: 16/06/2010, 17h22
  5. surcharge operateur = avec type strucutre en retour
    Par krossark dans le forum Langage
    Réponses: 3
    Dernier message: 28/01/2010, 10h26

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