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 :

Probleme de const


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2014
    Messages
    11
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Enseignement

    Informations forums :
    Inscription : Mars 2014
    Messages : 11
    Par défaut Probleme de const
    Bonjour,

    Je suis actuellement en train de réaliser une petite application. Ce message d'erreur est apparu à la compilation :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    error: passing ‘const XXX’ as ‘this’ argument of ‘void XXX::Load(std::ifstream&)’ discards qualifiers [-fpermissive]
        _XXX->Load(flux);
                           ^
    XXX est un pointeur d'objet déclaré comme ceci dans la classe:
    Dans chacune des méthodes de la classe je passe bien un const XXX.
    J'avoue que la je suis un peu perdu et la résolution du problème m'échappe

    Merci d'avance pour l'aide ou piste de solution que vous pourriez m'apporter

  2. #2
    Membre Expert
    Avatar de Pyramidev
    Homme Profil pro
    Tech Lead
    Inscrit en
    Avril 2016
    Messages
    1 513
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Tech Lead

    Informations forums :
    Inscription : Avril 2016
    Messages : 1 513
    Par défaut
    Bonjour.

    Si XXX est le nom d'une classe alors, quand tu écris const XXX _XXX;, _XXX n'est pas un pointeur, mais une instance de classe de type const XXX.
    Alors, pour appeler une fonction void XXX::FonctionConstante() const avec _XXX, la syntaxe n'est pas _XXX->FonctionConstante() mais _XXX.FonctionConstante().
    Attention : Comme _XXX est constant, alors on ne peut appeler que des fonctions constantes. Dans ton message, on voit que void XXX::Load(std::ifstream&) n'est pas constante, ce qui est normal, puisqu'une fonction qui charge des données dans un objet modifie cet objet. Donc, avec ton code actuel, _XXX.Load(flux) ne compilera pas.

    La solution dépend de ton code. Peut-être que la solution suivante conviendra :
    Dans ta classe XXX, si tu ajoutes un constructeur qui prend en paramètre std::ifstream& flux et qui appelle Load(flux), alors tu pourras construire un objet de type const XXX avec l'instruction const XXX _XXX{flux};.
    En général, quand un objet a besoin de charger des données, il vaut mieux les charger dans le constructeur. Comme ça, on garantie que le chargement des données se fait bien avant l'utilisation de l'objet.

  3. #3
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2014
    Messages
    11
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Enseignement

    Informations forums :
    Inscription : Mars 2014
    Messages : 11
    Par défaut
    Merci de votre réponse

    Il est possible que je change la déclaration de mon objet par ceci:

    Est-ce qu'une autre solution peut être envisager avec cette modification ?

  4. #4
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 152
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 152
    Billets dans le blog
    4
    Par défaut
    Ton pointeur pointe toujours vers un objet constant donc seules les fonctions const peuvent être appelées.
    - pourquoi le membre serait const ?
    - load est sensé charger un objet depuis des données et n'a aucune chance d'être const si la logique tient..
    - pourquoi tu chargerais/modifierais un objet const ?
    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
    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,

    Ce qu'il faut comprendre, c'est que le mot clé const agit comme un grand panneau triangulaire rouge "attention, cette donnée ne peut pas être modifiée" pour le compilateur. C'est une règle que tu lui donne à laquelle il ne pourra contrevenir sous aucun prétexte. Quand tu appliques ce mot clé à une instance de classe, par exemple, en déclarant une variable sous la forme dele compilateur acceptera que tu ne fasse appel qu'aux fonctions membres de MaClasse qui se sont explicitement engagées à ne pas modifier l'instance en cours. Comment en faisant suivre l'accolade (edit) la parenthèse fermante de la fonction du mot clé const. Allez, un petit exemple pour t'aider à comprendre:

    Mettons que j'écrive une classe proche de
    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
    class MaClasse{
    public:
        MaClasse(int i):m_i{i}{}
        /* cette fonction ne s'engage pas à ne pas modifier l'instance courante
         * et c'est tant mieux, car elle modifie la valeur de m_i
         */
        void add3(){
            m_i+=3;
        }
        /* par contre, cette fonction s'engage EXPLICITEMENT à ne pas modifier
         * l'instance en cours car elle est suivie du mot clé const
         */
        int get() const{
            return m_i;
        }
    private:
        int m_i;
    };
    Cette classe pourrait être utilisée sous la forme de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    int main(){
         MaClasse c{4}; // c.m_i vaut 4;
         c.add3(); //   c.m_i vaut maintenant 7
         std::cout<<"Après appel de add3(), m_i vaut "<<c.get();
    }
    Ce code sera accepté car c n'est pas considéré comme étant constante. on peut donc "sans aucun problème" faire appel à toutes les fonctions exposées par MaClasse.

    Par contre, si tu déclares ta une variable (de type MaClasse) comme étant constante, le compilateur refusera que tu fasse appel à toute fonction susceptible de modifier l'instance de la classe. Et comment le détermine-t-il au niveau des fonctions membres Pour lui, c'est très simple : toute fonction qui ne s'est pas explicitement engagée à ne pas modifier l'instance courante risque de le faire.

    Si bien que, dans mon exemple, il n'y a que la fonction get qui ne modifiera effectivement pas (aux yeux du compilateur) l'instance courante.
    Ainsi, un code proche de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    int main(){
        MaClasse const c{4}; // c est CONSTANTE on ne peut appeler
                             // QUE DES FONCTIONS QUI NE MODIFIENT PAS c
        std::cout<<"c.i vaut "<<c.get(); //OK: get s'est engagé à ne pas modifier l'instance courante
     
    }
    sera accepté. Par contre, un code proche de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    int main(){
        MaClasse const c{4}; // c est CONSTANTE on ne peut appeler
                             // QUE DES FONCTIONS QUI NE MODIFIENT PAS c
        c.add3(); // NOK: add3() modifie c... et on a dit que c ne POUVAIT PAS ÊTRE MODIFIE
    }
    sera refusé car l'appel à add3() "désactive le qualificateur de constance".

    Il n'est pas question de pointeur Vs valeur VS référence dans le cas présent. Il est juste question du fait que quelque chose qui est déclaré comme constant ne peut par définition même ... pas être modifié

    Il est possible que je change la déclaration de mon objet par ceci:
    Attention! il y a une énorme différence entre déclarer une variable sous la forme de
    et le fait de la délcarer sous la forme de
    (la présence ou l'absence du mot clé const étant ici "anecdotique"):

    Dans le premier cas, tu déclare une valeur de type XXX appelée _xxx, dans le deuxième cas, tu déclares un pointeur sensé représenté l'adresse à laquelle tu trouvera un élément de type XXX et qui s'appelle _xxx.

    De manière générale, on préférera éviter le recours aux pointeurs autant que faire se peut. Mieux encore : on décidera de n'avoir recours aux pointeurs que si on n'a pas d'autre choix. Or, avec la notion de référence et les classes comme std::reference_wrapper ou d'autres, on se retrouve à n'avoir que de moins en moins souvent besoin de recourir aux pointeurs.

    Et, quoi qu'il en soit, chaque fois que l'on y aura recours, on préféreras les "englober" dans des classes qui se chargeront de libérer correctement la ressource pointée en temps opportuns comme std::unique_ptr ou std::shared_ptr
    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

  6. #6
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2014
    Messages
    11
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Enseignement

    Informations forums :
    Inscription : Mars 2014
    Messages : 11
    Par défaut
    Merci à vous deux pour les éclaircissement apportées

    L'idée que j'avais au départ était absurde, j'ai enlevé les const qui n'avait rien a faire et tout tourne

    Merci aussi du rappel de théorie qui m'a beaucoup aidé j'ai sauvé ca dans un word

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

Discussions similaires

  1. Probleme avec const char*
    Par michastro dans le forum Débuter
    Réponses: 10
    Dernier message: 07/04/2016, 14h47
  2. probleme de const et cache
    Par themadmax dans le forum C++
    Réponses: 6
    Dernier message: 15/03/2012, 15h48
  3. Probleme utilisation const void*
    Par mansgueg dans le forum C++
    Réponses: 5
    Dernier message: 07/03/2011, 20h39
  4. probleme de "const correctness"
    Par GuiYom00 dans le forum C
    Réponses: 2
    Dernier message: 13/10/2008, 14h21
  5. probleme avec le mot const et operateur==
    Par elekis dans le forum C++
    Réponses: 4
    Dernier message: 06/05/2005, 13h21

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