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 :

priorité des opérateurs surchargés


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Homme Profil pro
    Collégien
    Inscrit en
    Mars 2003
    Messages
    192
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Afghanistan

    Informations professionnelles :
    Activité : Collégien

    Informations forums :
    Inscription : Mars 2003
    Messages : 192
    Par défaut priorité des opérateurs surchargés
    Salut,

    Je suis en train de coder une petite classe de vecteurs (l'objet mathématique). Je code notamment les opérations produit scalaire, produit vectoriel etc...

    J'ai ajouté des opérateurs amis ostream pour afficher mes vecteurs facilement à l'écran.

    Imaginons que v1 et v2 soient deux vecteurs à 3 composantes v1(1,1,1) et v2(2,2,2).

    Si * est l'opérateur de produit scalaire, alors v1*v2 donne 6.

    je peux faire

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    vec v3;
    v3 = v1*v2;
    cout << v3 << endl;

    mais je ne peux pas faire

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    cout << v1*v2 << endl;
    sans avoir d'erreur à la compilation. Ce que je comprends c'est que le compilateur ne sait pas s'il doit appliquer l'opérateur '<<' avant ou après l'opérateur '*' dans l'instruction.

    Comment coder des règles de priorités entre les opérateurs surchargés ?


    voici la partie "concernée" par le problème, 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
     
    class vec
    {
    private :
    vector<double>c;
     
    public:
    vec();												
    vec(const double c0, const double c1, const double c2);
     
    //accesseurs en lecture/ecriture
    double & operator()(unsigned int);
    double   operator()(unsigned int ) const;
     
    //opérateurs surchargés
    vec operator+(const vec &) const;
    vec operator*(const double ) const;
    double operator*(const vec &)   const;
    vec operator^(const vec &) const;
    vec operator/(const double ) const;
    operator /vec & operator+=(const vec &);
     
    friend ostream  & operator<<(ostream &, const vec &);
    };

    Bien sûr je peux mettre des parenthèses autour de (v1*v2), mais je ne veux pas...


    Merci,
    A+

  2. #2
    Membre Expert
    Avatar de Franck Dernoncourt
    Homme Profil pro
    PhD student in AI @ MIT
    Inscrit en
    Avril 2010
    Messages
    894
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : PhD student in AI @ MIT
    Secteur : Enseignement

    Informations forums :
    Inscription : Avril 2010
    Messages : 894
    Par défaut
    Citation Envoyé par Heimdall
    Le compilateur ne sait pas s'il doit appliquer l'opérateur '<<' avant ou après l'opérateur '*' dans l'instruction.
    Si : http://en.wikipedia.org/wiki/Operato...tor_precedence
    An operator's precedence is unaffected by overloading.

  3. #3
    screetch
    Invité(e)
    Par défaut
    toujours mettre l'erreur du compilateur

  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
    Par défaut
    Salut,
    1/ On ne peut pas modifier la priorité des opérateurs

    2/ Avec l'opérateur * cela marche très bien car l'opérateur * est bien plus prioritaire :
    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
    #include <iostream>
    class vec
    {
    private :
     
    public:
        vec operator*(const vec &) const{return *this;}
     
        friend std::ostream  & operator<<(std::ostream &, const vec &);
    };
     
    std::ostream  & operator<<(std::ostream &o, const vec &)
    {
        return o;
    }
     
    int main()
    {
        vec v1,v2;
        vec v3;
     
        v3 = v1*v2;
        std::cout << v3 << std::endl;
        std::cout << v1*v2 << std::endl;
     
        return 0;
    }
    3/ L'opérateur ^, il faut parenthéser car l'opérateur est - prioritaire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    #include <iostream>
     
    int main()
    {
        int i,j;
        std::cout<<i^j<<std::endl; // erreur
        std::cout<<(i^j)<<std::endl; // OK
     
        return 0;
    }
    4/ L'interface de ta classe est très perturbante. Il est assez peu intuitif de comprendre tes surcharges :

    5/ On essaie en générale de garder une sémantique usuelle pour les surcharges d'opérateurs. Pour la surcharge de l'opérateur * avec 2 vecteurs, je me demanderai toujours si c'est un produit scalaire, un produit vectoriel... Bref, pas bonne idée : autant donner un nom de fonction explicite. L'opérateur, c'est bien pour un vecteur par un scalaire car il n'y a pas d’ambiguïté.

  5. #5
    Membre confirmé
    Homme Profil pro
    Collégien
    Inscrit en
    Mars 2003
    Messages
    192
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Afghanistan

    Informations professionnelles :
    Activité : Collégien

    Informations forums :
    Inscription : Mars 2003
    Messages : 192
    Par défaut
    Re,

    en effet, je ne sais pas pourquoi mais le v1*v2 a marché... j'ai du réver et confondre avec la ligne qui testait le produit vectoriel.

    Pour ce qui est de l'interface... en fait perso le '^' m'allait bien car en france, il correspond au même symbole que symbole mathématique de produit vectoriel.
    Dans les notations anglophones, c'est le 'x' (cross-product) mais qui n'existe pas ici...

    Pour ce qui est du produit scalaire, pareil on ne peut pas surcharger le '.', qui est la notation mathématique usuelle... j'ai donc choisi le '*'.


    Avant je voulais faire ceci :


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    double operator*(const vec &) const; // produit scalaire
    vec operator*(const vec &) const;     // produit vectoriel

    i.e. surcharger deux fois l'opérateur '*' pour que, lorsqu'on fasse :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    vec v1, v2, v3;
    double a;
     
    v1 = v2*v3;
    a = v2*v3;

    on utilise l'un ou l'autre.... mais ça ne passe pas à la compilation, je ne comprends pas trop pourquoi... le compilateur devrait savoir quel opérateur utiliser en regardant la variable ('a' ou 'v1') qui se trouve a gauche de l'opérateur... mais non...


    Personnellement, j'aime bien faire des opérations mathématiques avec mes vecteurs sans qu'il n'apparaisse de nom de fonction dans mon code, je trouve ça plus "joli".

    Dans le code d'une formule :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    double a;
    vec v1, v2;
     
    a = v1*v2;
    il n'y a de toute façon pas d'ambiguité, si 'a' est un scalaire, le '*' ne peut être qu'un produit scalaire...

  6. #6
    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
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    class vec;
    std::ostream& operator<<(std::ostream&,vec const&);
    // existe déjà  std::ostream& std::ostream::operator<<(double);
     
    // ....
    vec v1;
    vec v2;
     
    std::cout<<v1*v2<<"\n";
    Produit vectoriel ? Produit scalaire ? Produit tensoriel ? etc.

Discussions similaires

  1. Priorité des opérateurs surchargés dans un cas ambigu
    Par armapython dans le forum Général Python
    Réponses: 9
    Dernier message: 21/05/2014, 12h30
  2. [OCaml & F#] Priorité des opérateurs
    Par SpiceGuid dans le forum Caml
    Réponses: 7
    Dernier message: 01/01/2008, 15h00
  3. priorité des opérateurs
    Par new_wave dans le forum SQL
    Réponses: 13
    Dernier message: 08/11/2007, 21h44
  4. Priorité des opérateurs
    Par neuromencien dans le forum Langage
    Réponses: 3
    Dernier message: 14/05/2007, 17h06
  5. Réponses: 3
    Dernier message: 31/08/2006, 10h39

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