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 et cache


Sujet :

C++

Vue hybride

Message pr�c�dent Message pr�c�dent   Message suivant Message suivant
  1. #1
    Membre chevronn� Avatar de themadmax
    Profil pro
    Inscrit en
    Juillet 2005
    Messages
    446
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2005
    Messages : 446
    Par d�faut probleme de const et cache
    Bonjour,

    J'ai un petit probl�me, j'ai des accesseurs qui mettent � jour des membres de ma classe si celle-ci n'est pas encore initialis�. Le probl�me c'est que je ne peux d�clar� ces accesseur comme const, et que cela ce r�percute sur tout le reste de mon programme. Avez-vous une astuce pour ce genre de probl�me ?

    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    class Toto
    {
       string _name ;
       bool _init;
       const string& getName() /* j'aimerai mettre const */
       { 
          if(!_init) init(); //fonction non const
          return _name ;
       }
       void init() { _name = "operation longue"; _init = true; } //fonction non const
    }
    Merci d'avance

  2. #2
    R�dacteur/Mod�rateur
    Avatar de JolyLoic
    Homme Profil pro
    D�veloppeur informatique
    Inscrit en
    Ao�t 2004
    Messages
    5 463
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    �ge : 51
    Localisation : France, Yvelines (�le de France)

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

    Informations forums :
    Inscription : Ao�t 2004
    Messages : 5 463
    Par d�faut
    D�clares tes variables de ce type mutable
    Ma session aux Microsoft TechDays 2013 : D�velopper en natif avec C++11.
    Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
    Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage � la d�couverte d'un nouveau monde
    Je donne des formations au C++ en entreprise, n'h�sitez pas � me contacter.

  3. #3
    Membre �m�rite
    Avatar de Ekleog
    Homme Profil pro
    �tudiant
    Inscrit en
    Janvier 2012
    Messages
    448
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activit� : �tudiant

    Informations forums :
    Inscription : Janvier 2012
    Messages : 448
    Par d�faut
    Au passage, pourquoi ne pas initialiser dans le constructeur ?

  4. #4
    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,

    En effet, il serait sans doute pr�f�rable d'utiliser le constructeur ( apr�s tout, il sert � ca, non ), ce qui donnerait quelque chose comme
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    class Toto
    {
        public:
            Toto():name_("operation longue"){}
            Toto(std::string const & name):name_(name){}
            std::string const & name() const{return name_;}
        private:
            std::string name_;
    };
    Tu n'aurais ainsi meme plus � t'inqui�ter de savoir si l'objet est effectivement initialis�, ce qui ne peut qu'etre b�n�fique

    En outre, en travaillant de la mani�re que tu pr�sente, tu risques d'avoir un effet de bord pour le moins d�sagr�able:

    Si tu rajoutes n'importe quelle fonction qui teste ou modifie le membre name_ � ta classe, le r�sultat sera diff�rent en fonction du fait que l'utilisateur aura (ou non) d�j� invoqu� la fonction name() (ou la fonction init() ) , ce qui retire toute chance de pr�dicabilit� du r�sultat:
    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
    28
    29
    30
    31
    32
    33
    34
     
    class Toto
    {
        public:
            bool isCorrect() const
            {
                return name_=="test";
            }
            std::string const & name() const
            {
                if(!initialized_)
                    init();
                return name_;
            }
            void init()
            {
                name_="test";
                initialized_ = true;
            }
        private:
            bool initialized_;
            std::string name_;
    };
    int main()
    {
        Toto t;
        std::cout<< t.isCorrect(); // sortie : 0 (false)
        t.name();
        sttd::cout<<t.isCorrect(); // sortie : 1 (true) on n'a pourtant pas invoqué
                                   // sciemment init !!!
        Toto t2;
        t2.init(); //que doit on faire, appeler init, ou name ???
        return 0;
    }
    Ceci dit, le mot cl� mutable pr�sente l'�norme inconv�nient de supprimer tout controle de constance sur le membre d�fini mutable

    Une solution, qui, de plus, a l'avantage d'attirer l'attention du lecteur de code sur le fait que l'on d�cide de mani�re r�fl�chie et limit�e de passer outre de la constance de l'objet peut etre le recours au const_cast:
    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
    28
    29
    30
    31
    class Holder
    {
        /* juste pour la facilité d'écriture ;) */
        typedef std::vector<Type> vector;
        public:
            typedef typename vector::const_iterator const_iterator;
            Holder():needToBeSorted_(false),items_(){}
            /* les fonctions qui vont réellement modifier l'objet */
            void add(Type const &  toadd) 
            {
                items_.push_back(toadd);
                needToBeSorted_ = true;
            }
            /* une fonction qui ne modifie pas forcément l'état de l'objet */
            const_iterator find(DataType const & value) const
            {
                const_cast<Holder &>(*this).sort();
                const_iterator it;
                /* rechercher l'élément en question */
                return it;
            }
        private:
            void sort()
            {
                 if(needToBeSorted_)
                     std::sort(items_.begin(),items_.end());
                  needToBeSorted_ = false;
            }
            bool needToBeSorted_;
            vector items_;
    };
    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
    R�dacteur/Mod�rateur
    Avatar de JolyLoic
    Homme Profil pro
    D�veloppeur informatique
    Inscrit en
    Ao�t 2004
    Messages
    5 463
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    �ge : 51
    Localisation : France, Yvelines (�le de France)

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

    Informations forums :
    Inscription : Ao�t 2004
    Messages : 5 463
    Par d�faut
    Franchement, je n'aime pas ta proposition � base de const_cast, et lui pr�f�re largement mutable.

    D�j�, mutable, il suffit de lire la d�claration de la classe pour savoir qu'une donn�e membre est sp�ciale, et que la constance logique de la classe ne d�pendra pas de la constance de cette donn�e membre. Je pense important de savoir le r�le de cette donn�e d�s sa d�claration. C'est une information sur le design de la classe, pas un d�tail d'impl�mentation. Quand on lit bool needToBeSorted_;, on ne sait pas trop le r�le de cette variable. Si on lit mutable bool needToBeSorted_;, on sait tout de suite que la classe va impl�menter un m�canisme de cache d'information, et que cette variable va avoir un r�le clef dans le m�canisme.

    En contraste, avec const_cast, il faut lire l'ensemble des impl�mentations des fonctions pour comprendre le r�le de cette variable.

    Ensuite, ton exemple avec const_cast n'est pas l�gal
    En effet, const_cast ne permet pas de modifier un objet constant (un tel objet pourrait avoir �t� �crit dans de la m�moire non modifiable). Il permet juste deux choses :
    - De faire taire le syst�me de type quand on doit passer une valeur constante � un fonction qui n'a pas d�clar� qu'elle ne la modifiera pas, mais qui en pratique ne la modifiera pas. Tr�s pratique pour s'interfacer avec du vieux code C.
    - Quand on a une variable que l'on sait �tre modifiable, mais qu'on n'y a acc�s que par un chemin o� cette information a �t� perdue. Comme un int auquel on n'a acc�s que par un int const *.
    Pour plus de d�tails, lire le �7.1.6.1 (en particulier l'exemple paragraphe 5).
    Ma session aux Microsoft TechDays 2013 : D�velopper en natif avec C++11.
    Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
    Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage � la d�couverte d'un nouveau monde
    Je donne des formations au C++ en entreprise, n'h�sitez pas � me contacter.

  6. #6
    R�dacteur/Mod�rateur
    Avatar de JolyLoic
    Homme Profil pro
    D�veloppeur informatique
    Inscrit en
    Ao�t 2004
    Messages
    5 463
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    �ge : 51
    Localisation : France, Yvelines (�le de France)

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

    Informations forums :
    Inscription : Ao�t 2004
    Messages : 5 463
    Par d�faut
    Citation Envoy� par Ekleog Voir le message
    Au passage, pourquoi ne pas initialiser dans le constructeur ?
    Citation Envoy� par koala01 Voir le message
    En effet, il serait sans doute pr�f�rable d'utiliser le constructeur ( apr�s tout, il sert � ca, non ), ce qui donnerait quelque chose comme
    [...]
    Tu n'aurais ainsi meme plus � t'inqui�ter de savoir si l'objet est effectivement initialis�, ce qui ne peut qu'etre b�n�fique
    En r�gle g�n�rale, je suis d'accord avec vous deux. Il y a pourtant parfois des cas o� cette r�gle g�n�rale ne s'applique pas, en particulier quand cette initialisation est tr�s co�teuse, et que dans un grand nombre de cas, elle ne sera pas utilis�e.

    Il peut �tre alors int�ressant de mettre en place un m�canisme "lazy" qui fera uniquement l'initialisation dans les rares cas o� elle est requise.
    Ma session aux Microsoft TechDays 2013 : D�velopper en natif avec C++11.
    Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
    Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage � la d�couverte d'un nouveau monde
    Je donne des formations au C++ en entreprise, n'h�sitez pas � me contacter.

  7. #7
    Membre chevronn� Avatar de themadmax
    Profil pro
    Inscrit en
    Juillet 2005
    Messages
    446
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2005
    Messages : 446
    Par d�faut
    Citation Envoy� par Ekleog Voir le message
    Au passage, pourquoi ne pas initialiser dans le constructeur ?
    En effet, dans le cas g�n�ral il faudrait initialis� le contenu dans le constructeur mais l�op�ration d�initialisation est assez couteuse en temps et surtout elle n'est pas demander � chaque fois mon objet peut �tre cr�er sans jamais avoir d'appel � la fonction getName().
    Il me semble que la solution mutable semble convenir � mon probl�me.

    @koala01 il est vrai qu'il ne faut jamais pass� par le membre directement, mais utilis� l�accesseur qu'il lui correspond. Pour la class Holder je la garde de cot�...

    Merci pour vos r�ponses pr�cises

+ R�pondre � la discussion
Cette discussion est r�solue.

Discussions similaires

  1. probleme avec les dossier cach�
    Par beusedogg dans le forum Windows 7
    R�ponses: 3
    Dernier message: 17/07/2011, 18h18
  2. [eZ Publish] probleme avec les noeuds cach�s
    Par dev-deb dans le forum EDI, CMS, Outils, Scripts et API
    R�ponses: 2
    Dernier message: 19/05/2011, 14h33
  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 de mise en cache
    Par TRUNKS-SSJ7 dans le forum Balisage (X)HTML et validation W3C
    R�ponses: 5
    Dernier message: 25/03/2007, 20h08

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