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 :

modifier un attribut avec une fonction const?


Sujet :

C++

  1. #1
    Membre actif
    Avatar de katanaenmousse
    Profil pro
    Inscrit en
    octobre 2008
    Messages
    215
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : octobre 2008
    Messages : 215
    Points : 226
    Points
    226
    Par défaut modifier un attribut avec une fonction const?
    Bonjour,
    voici mon .h et mon .cpp :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    
    class ClasseA: public ClasseB{ 
      
    public: 
        explicit ClasseA();
        void maFonction(int i) const override; 
    
    private: 
        std::set <int> maliste; 
    };


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    ClasseA::ClasseA(): ClasseB()
    { 
    } 
    void ClasseA::maFonction(int i)const { maliste.insert(i); }

    J'ai une question assez simple : Est ce que ma fonction maFonction(int i) pourra ajouter des valeurs dans maliste sachant que cette fonction est declarée const et que je ne peux pas changer ça vu que je l'override?
    Et y a t il un moyen pour y parvenir?

    Merci à vous
    KatanaEnMousse
    Une fois qu'une réponse qui vous convient a été trouvée à votre sujet, pensez à le mettre en résolu.

  2. #2
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    octobre 2004
    Messages
    11 511
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : octobre 2004
    Messages : 11 511
    Points : 29 908
    Points
    29 908
    Par défaut
    Salut,

    Le mot clé const indique explicitement que la fonction n'est pas sensée modifier l'état de ta classe.

    Tu ne peux donc pas -- a priori -- envisager de modifier les données membres de ta classes avec cette fonction.

    Cependant, tu peux considérer qu'une des données représente d'avantage des données en cache qu'autre chose, et que le cache devra être mis à jour de manière régulière, malgré le fait cela ne modifie pas l'état interne de la classe.

    Soyons clairs: cette possibilité n'est absolument pas adaptable à toutes les situations!!! En fonction de ce qu'est ClasseA, du service rendu par maFonction et de l'utilité à laquelle tu destines maListe, la possibilité que maliste puisse -- effectivement -- être considérée comme une donnée de cache est particulièrement faible!

    Mais si tel est effectivement le cas, il "suffit" de déclarer maliste comme étant mutable:

    Le code, tel que tu le présentes sera carrément refusé par le compilateur sous prétexte que "l'insertion d'un élément dans set va à l'encontre du (cv) qualifier", mais si tu déclares maliste, voir, parce que la seule version de insert qu'il trouve dans la classe set est une version non constante, alors qu'il ne peut utiliser que des fonctions constantes à l'intérieur d'une fonction membre constante.

    Mais si tu déclares maliste, il acceptera de faire appel à la version non constante de insert

    Je vais me répéter, mais, je tiens à ce que les choses soient bien claires : cette possibilité t'offre l'occasion de mettre à bat tout le système de contrôle de la const correctness. Si tu en as absolument besoin, fais le. Mais l'idéal -- comme pour tant de choses que le langage autorise mais qui ne sont en définitive que que fausses bonnes idées dans la plupart des cas -- reste malgré tout de s'en passer si l'on peut faire autrement
    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 actif
    Avatar de katanaenmousse
    Profil pro
    Inscrit en
    octobre 2008
    Messages
    215
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : octobre 2008
    Messages : 215
    Points : 226
    Points
    226
    Par défaut
    Merci Koala pour ta réponse très précise.
    Effectivement j avais depuis longtemps pris l habitude d éviter «*mutable*»
    J en étais venu à penser qu il ne fallait pas l utiliser.
    Mais parfois effectivement il faut s en servir
    Merci pour ce rappel et ces éclairages
    Merci beaucoup
    KatanaEnMousse
    Une fois qu'une réponse qui vous convient a été trouvée à votre sujet, pensez à le mettre en résolu.

  4. #4
    Expert confirmé
    Avatar de Pyramidev
    Homme Profil pro
    Développeur
    Inscrit en
    avril 2016
    Messages
    1 242
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur

    Informations forums :
    Inscription : avril 2016
    Messages : 1 242
    Points : 5 204
    Points
    5 204
    Par défaut
    Bonjour,

    Je pressens une mauvaise utilisation de mutable.
    Que représentent ClasseA, ClasseB et maFonction ?
    Pourquoi ClasseB::maFonction est-elle const ?

    En tout cas, on peut contourner la constness de ClasseB::maFonction ainsi :
    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
    class ClasseB {
    public:
    	virtual ~ClasseB() {}
    	virtual void maFonction(int i) const = 0;
    };
     
    class ClasseA final {
    public:
    	ClasseA() {}
    	void maFonction(int i) { m_set.insert(i); }
    private:
    	std::set<int> m_set;
    };
     
    class ClasseARef final : public ClasseB {
    public:
    	explicit ClasseARef(ClasseA& ref) : ClasseB{}, m_ref{ref} {}
    	void maFonction(int i) const override { m_ref.maFonction(i); }
    private:
    	ClasseA& m_ref;
    };

  5. #5
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    octobre 2004
    Messages
    11 511
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : octobre 2004
    Messages : 11 511
    Points : 29 908
    Points
    29 908
    Par défaut
    Je suis, moi aussi, quasiment certain que tu ne veux pas utiliser mutable dans ta situation, que, soit, tu dois supprimer le cv-qualifier de la fonction, soit tu ne veux purement et simplement pas modifier ta liste à cet endroit.

    La possibilité d'utiliser mutable existe, mais, quoi que l'on puisse en dire, il faut rester bien conscient du fait que la const correctness est ta meilleure amie:

    C'est la base sur laquelle tu peux t'appuyer pour être en mesure de déterminer si une donnée risque d'être modifiée ou non. Et c'est donc la base sur laquelle tu peux partir de situation claires et précises.

    L'utilisation met cette base à mal, en te permettant de modifier une donnée qui n'a -- normalement -- aucune raison de pouvoir l'être. C'est certes pratique, vu que cela permet des choses "impossibles", mais cela implique que tu ne peux plus faire confiance à la constance pour t'assurer que les données ne subissent aucune modification entre deux appels de fonctions. Et ca, c'est loin d'être une situation idéale.

    Le fait, est que tu nous as présenté un problème tout à fait général, sans donner la moindre notion du contexte dans lequel tu te trouves effectivement. je me suis donc limité à fournir une solution générale, dont j'ai pris la peine de mettre les dangers en avants.

    Mais, si j'avais eu connaissance du contexte réel auquel tu es confronté, j'aurais sans doute pu fournir une alternative bien moins dangereuse et sans doute même bien plus efficace à long terme
    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

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

Discussions similaires

  1. Problème avec une fonction const et une référence & !
    Par Seabast888 dans le forum Débuter
    Réponses: 2
    Dernier message: 19/10/2009, 14h08
  2. Définir une "Public Const" avec une fonction
    Par bernardmichel dans le forum VBA Access
    Réponses: 6
    Dernier message: 29/09/2007, 16h16
  3. Réponses: 1
    Dernier message: 16/03/2007, 18h30
  4. mem_fun avec une fonction const
    Par olive_le_malin dans le forum C++
    Réponses: 4
    Dernier message: 20/02/2007, 19h22
  5. Modifier un champs texte avec une fonction PHP (calcul TVA)
    Par Stella2809 dans le forum Général JavaScript
    Réponses: 1
    Dernier message: 22/11/2005, 01h55

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