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 operateur () et const


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé
    Profil pro
    Inscrit en
    Février 2006
    Messages
    396
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Février 2006
    Messages : 396
    Par défaut Surcharge operateur () et const
    Bonjour,

    Je viens de trouver ce code source:
    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
    template<class T> inline T& Matrix4<T>::operator ()(size_t i, size_t j)
    {
    	return operator T*()[j * 4 + i];
    }
     
    template<class T> inline const T& Matrix4<T>::operator ()(size_t i, size_t j) const
    {
    	return operator ()(i, j);
    }
     
    template<class T> inline Matrix4<T>::operator T*()
    {
    	return &a11;
    }
     
    template<class T> inline Matrix4<T>::operator const T*() const
    {
    	return &a11;
    }
    Il y a deux fois la même fonction avec "const" et sans "const". Quand est-ce que le compilateur va choisir l'une ou l'autre ?
    Ou est-ce peut-être une erreur de programmation ? Dans ce cas pourquoi le compilateur ne l'interdit pas ?

    J'ai l'impression que ma deuxième méthode me fait un seg fault et je crois qu'elle essaye de s'appeler elle même à l'infini mais je ne suis pas certain. Est-ce possible ?

    Merci d'avance.

  2. #2
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par défaut
    Salut,

    Non, il n'y a strictement aucune erreur

    La constance d'une fonction membre fait partie intégrante de la signature (comprend : la partie prise en compte par le compilateur lors de l'appel ) de la fonction, et intervient dans le respect de ce que l'on appelle la const correctness.

    A défaut de traduction "officielle" du terme, disons que la const correctness est le principe qui veut qu'un objet considéré constant ne peut en aucun cas être modifié, même de manière indirecte

    L'idée générale est que l'on peut toujours augmenter le niveau de constance (comprend : considérer un objet non constant à la base comme s'il s'agissait d'un objet non constant), mais que l'on ne peut jamais le diminuer implicitement (comprend: considérer un objet constant à la base comme s'il n'était pas constant).

    On peut donc appeler n'importe quelle fonction depuis un objet non constant : aussi bien les fonction non constantes (comprend : qui ne se sont pas engagées à ne pas modifier l'objet au départ duquel elles sont appelées) que des fonctions constantes (comprends : qui se sont engagées faire en sorte que rien de ce qui sera fait ne provoquera une modification de l'objet au départ duquel elles sont appelées), mais on ne peut, par contre, appeler qu'uniquement des fonctions constantes depuis un objet constant.

    Pour déclarer une fonction constante, il "suffit" de faire suivre son prototype du mot clé const et, bien sur, de s'assurer le cas échéant que le retour de la fonction ne pourra pas être utilisé pour modifier l'objet (de toutes manières, le compilateur veillera au grain sur ce dernier point ).

    Le principe est, en gros, que le retour de fonction se fasse soit par valeur (dans ce cas, il y a copie de l'objet renvoyé, et il n'y a donc aucun lien entre l'objet utilisé dans la fonction appelante et le membre renvoyé ) soit par référence (ou par pointeur) constante.

    A ce moment là, même s'il n'y a pas copie de l'objet renvoyé, le compilateur n'acceptera pas que tu essayes d'invoquer une fonction ne s'étant pas engagée à ne pas le modifier .

    Dans le cas que tu nous montres, les opérateurs
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    template<class T> inline T& Matrix4<T>::operator ()(size_t i, size_t j)
    {
    	return operator T*()[j * 4 + i];
    }
    et
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    template<class T> inline Matrix4<T>::operator T*()
    {
    	return &a11;
    }
    ne pourront être appelés que depuis des objets non constants et permettront donc de modifier le membre (a11) de l'objet, mais ne pourraient pas être appelés depuis un objet constant (par exemple, si tu transmet ta Matrix4<T> par référence constante à une fonction).

    Et comme tu as (sans doute) besoin de pouvoir utiliser ces opérateurs sur des objets constants, il faut donc créer une version de ces opérateurs qui respecte les règles relative à la constance des objets

    C'est pour cela que tu as également les opérateurs
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    template<class T> inline const T& Matrix4<T>::operator ()(size_t i, size_t j) const
    {
    	return operator ()(i, j);
    }
    et
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    template<class T> inline Matrix4<T>::operator const T*() const
    {
    	return &a11;
    }


    Quand est-ce que le compilateur va choisir l'une ou l'autre ?
    Il va choisir la version constante dés que l'opérateur sera appelé depuis un objet (ou une référence) constant(e) et l'autre dés que l'opérateur sera invoqué depuis un objet (ou une référence) non constante
    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

  3. #3
    Membre Expert

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Août 2004
    Messages
    1 391
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Doubs (Franche Comté)

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

    Informations forums :
    Inscription : Août 2004
    Messages : 1 391
    Par défaut
    Bonjour,

    koala01 a du t'apporter toutes les réponses à ta première question.

    Pour la seconde, en effet tu as une fonction qui s'appelle indéfiniment, ce n'est pas une erreur syntaxique, mais plutôt une erreur de programmation.

    Je pense que l'auteur de ce code a voulu écrire un opérateur en fonction de l'autre, mais il s'y ai pris à l'envers. C'est la version non-const qu'il faut écrire en fonction de la const :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    struct A
    {
      int i;
      const int& operator()() const
      { return i; }
      int& operator()()
      { return const_cast<int&>(static_cast<const A&>(*this)()); }
    };

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

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    Citation Envoyé par Flob90 Voir le message
    Bonjour,

    koala01 a du t'apporter toutes les réponses à ta première question.

    Pour la seconde, en effet tu as une fonction qui s'appelle indéfiniment, ce n'est pas une erreur syntaxique, mais plutôt une erreur de programmation.

    Je pense que l'auteur de ce code a voulu écrire un opérateur en fonction de l'autre, mais il s'y ai pris à l'envers. C'est la version non-const qu'il faut écrire en fonction de la const :
    <snip>
    En effet. Toutefois, j'aurais évité le static_cast explicite pour dans la version non-const, je trouve ça plus lisible:
    Code C++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
      int& operator()() { 
        const A& rThisC = *this;
        return const_cast<int&>( rThisC() );
      }
    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.

  5. #5
    Membre Expert

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Août 2004
    Messages
    1 391
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Doubs (Franche Comté)

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

    Informations forums :
    Inscription : Août 2004
    Messages : 1 391
    Par défaut
    C'est une pure question d'esthétique après C'est purement personnel

  6. #6
    Membre éclairé
    Profil pro
    Inscrit en
    Février 2006
    Messages
    396
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Février 2006
    Messages : 396
    Par défaut
    Merci pour vos réponses très clairs.
    Je mourrai moins bête

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

Discussions similaires

  1. const et surcharge operateur via fct membre
    Par mensoif dans le forum Langage
    Réponses: 10
    Dernier message: 24/05/2010, 15h58
  2. surcharge operateur avec "const"
    Par Krishna dans le forum C++
    Réponses: 6
    Dernier message: 18/04/2008, 09h32
  3. [debutante] surcharge operateur <<
    Par norkius dans le forum Débuter
    Réponses: 3
    Dernier message: 24/10/2005, 12h20
  4. [Surcharge]Operateur<< avec une classe maison
    Par KeNnEdY dans le forum C++
    Réponses: 6
    Dernier message: 14/09/2005, 15h51
  5. surcharge operateur && pointeurs
    Par le y@m's dans le forum C++
    Réponses: 6
    Dernier message: 10/05/2005, 15h57

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