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

Langage C++ Discussion :

Initialisation map static


Sujet :

Langage C++

  1. #1
    Membre régulier
    Profil pro
    Étudiant
    Inscrit en
    Janvier 2008
    Messages
    253
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2008
    Messages : 253
    Points : 84
    Points
    84
    Par défaut Initialisation map static
    Citation Envoyé par r0d Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    class Mere
    {
    public: 
       Mere() { Init(); } // constructeur qui appelle Init()
     
    protected:
       virtual void Init() = 0;
    };
    Bonjour,

    Je me permets d'intervenir dans ce topic car le bout de code ci-dessus m'interpelle.
    Que doit-il se passer si on souhaite accéder à des valeurs de classes avant toute instanciation?

    Manifestement on est obligé de faire une initialisation dans le constructeur mais encore faut-il qu'on ai déjà appelé ce constructeur avant d'accéder aux membres statiques, qui plus est si ils sont publiques (privés/protégés c'est le même débat si on passe par des méthodes de classes).

    Je rencontre moi-même un cas de ce genre, sans extension pour l'instant mais j'y viendrai et je ne comprends pas pourquoi, par exemple, on ne peut pas écrire ça dans un cpp :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    std::map<std::string, bool> DataPrimitive::_SPECFIELDS_WRITERULES = {
    	{struct_::DataModel::FIELD_RECORD, false},
    	{struct_::DataModel::FIELD_VERSION, false},
    	{struct_::DataModel::FIELD_OBJID, false},
    	{struct_::DataModel::FIELD_SECOWNERID, true},
    	{struct_::DataModel::FIELD_CREATETIME, false},
    	{struct_::DataModel::FIELD_UPDATETIME, false},
    	{struct_::DataModel::FIELD_MAKETIME, true},
    	{struct_::DataModel::FIELD_REMOVETIME, true},
    	{struct_::DataModel::FIELD_COLLECINDEX, false}
    };

  2. #2
    r0d
    r0d est déconnecté
    Expert éminent

    Homme Profil pro
    tech lead c++ linux
    Inscrit en
    Août 2004
    Messages
    4 262
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : tech lead c++ linux

    Informations forums :
    Inscription : Août 2004
    Messages : 4 262
    Points : 6 680
    Points
    6 680
    Billets dans le blog
    2
    Par défaut
    Bonjour,

    je ne comprend pas ton message, mais le bout de code que j'avais commis et que tu as cité est faux.
    « L'effort par lequel toute chose tend à persévérer dans son être n'est rien de plus que l'essence actuelle de cette chose. »
    Spinoza — Éthique III, Proposition VII

  3. #3
    Membre régulier
    Profil pro
    Étudiant
    Inscrit en
    Janvier 2008
    Messages
    253
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2008
    Messages : 253
    Points : 84
    Points
    84
    Par défaut
    Bonjour,

    Si le code que j'ai cité est faux, mon message l'est peut-être aussi :s

    En fait le problème reste l'initialisation puis le remplissage de membres statiques, en particulier les std::map et dérivés dont le contenu est complexe.
    Dans le code que tu avais proposé (et j'ai vu ce fonctionnement ailleurs), je comprends qu'il faut créer une méthode qui s'assure de remplir le membre statique. Cette méthode serait exécutée à la construction de la première instance de la classe.

    Mon problème est que si je ne créé aucune instance de ma classe, les attributs statiques ne seront jamais remplis et c'est un vrai problème.
    Sachant que l'on peut accéder à ces membres publiquement ou au travers de méthodes statiques, il vaut mieux qu'ils le soient dès le début du runtime sans effet transitoires.

    Je connais l'initialisation statique de Java et c'est très proche du comportement que je souhaite obtenir (et qui semble être le point de départ du topic).

  4. #4
    r0d
    r0d est déconnecté
    Expert éminent

    Homme Profil pro
    tech lead c++ linux
    Inscrit en
    Août 2004
    Messages
    4 262
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : tech lead c++ linux

    Informations forums :
    Inscription : Août 2004
    Messages : 4 262
    Points : 6 680
    Points
    6 680
    Billets dans le blog
    2
    Par défaut
    Le code cité est faux car on n'a pas le droit d'appeler une fonction virtuelle dans le constructeur (voir le message de Bousk).

    Je ne sais pas comment c'est exactement en java (il faudra que je me renseigne, je vais en avoir besoin), mais en c++ une variable statique peut être considérée comme une variable globale. Si l'accès est public, alors tu peux la manipuler sans avoir besoin de construire l'objet qui la contient. Idem pour une méthode statique: tu peux l'appeler sans avoir besoin d'instancier la classe qui la contient.

    Par contre, il faut faire attention avec les variables statiques en c++, il y a quelques pièges; et je te conseille de lire la faq correspondante.

    Après, qu'on ait affaire à des données simples ou complexes, le problème est le même.
    « L'effort par lequel toute chose tend à persévérer dans son être n'est rien de plus que l'essence actuelle de cette chose. »
    Spinoza — Éthique III, Proposition VII

  5. #5
    Membre régulier
    Profil pro
    Étudiant
    Inscrit en
    Janvier 2008
    Messages
    253
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2008
    Messages : 253
    Points : 84
    Points
    84
    Par défaut
    Citation Envoyé par r0d Voir le message
    Le code cité est faux car on n'a pas le droit d'appeler une fonction virtuelle dans le constructeur (voir le message de Bousk).
    Bien compris, merci.

    Je ne sais pas comment c'est exactement en java (il faudra que je me renseigne, je vais en avoir besoin)
    En Java il existe un bloque de code "static { }" dans la définition de la classe permettant d'executer du code, principalement d'initialisation, au moment où elle est importée au runtime, avant toute instanciation et toute utilisation de ses membres statiques donc.

    mais en c++ une variable statique peut être considérée comme une variable globale. Si l'accès est public, alors tu peux la manipuler sans avoir besoin de construire l'objet qui la contient. Idem pour une méthode statique: tu peux l'appeler sans avoir besoin d'instancier la classe qui la contient.
    Sous Visual Studio j'essaye de remplir un membre statique comme suit en haut du .cpp de ma classe:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    const std::map<std::string, bool> DataPrimitive::_SPECFIELDS_WRITERULES = {
    	{struct_::DataModel::FIELD_RECORD, false},
    	{struct_::DataModel::FIELD_VERSION, false},
    	{struct_::DataModel::FIELD_OBJID, false},
    	{struct_::DataModel::FIELD_SECOWNERID, true},
    	{struct_::DataModel::FIELD_CREATETIME, false},
    	{struct_::DataModel::FIELD_UPDATETIME, false},
    	{struct_::DataModel::FIELD_MAKETIME, true},
    	{struct_::DataModel::FIELD_REMOVETIME, true},
    	{struct_::DataModel::FIELD_COLLECINDEX, false}
    };
    J'ai pris le soin de le déclarer comme suit dans le .h:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    public: static const std::map<std::string, bool> _SPECFIELDS_WRITERULES;
    Mais je reçois une erreur me disant que je ne peux initialiser un membre de type std::map<std::string, bool> avec "{...}"

    C'est en cherchant d'autres méthodes que je suis tombé sur ce topic et l'astuce de passer par une méthode appelée dans le constructeur mais ca n'est pas satisfaisant de mon point de vue.

    Merci & bonne après-midi

  6. #6
    Rédacteur/Modérateur


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

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 116
    Points : 32 969
    Points
    32 969
    Billets dans le blog
    4
    Par défaut
    http://www.cplusplus.com/reference/map/map/map/

    Ton erreur est totalement différente et plutôt explicite.
    Cette syntaxe est peut-être disponible avec C++11 je ne sais pas, mais c'est un appel à un constructeur que tu dois effectuer.
    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.

  7. #7
    Membre habitué
    Profil pro
    Inscrit en
    Mars 2010
    Messages
    118
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2010
    Messages : 118
    Points : 158
    Points
    158
    Par défaut
    La syntaxe employé est correcte en C++11 pourvu que le typage soit correcte.

    Penser à activer l'option adéquate de son compilo pour la prise en charge de C++11.

  8. #8
    Membre régulier
    Profil pro
    Étudiant
    Inscrit en
    Janvier 2008
    Messages
    253
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2008
    Messages : 253
    Points : 84
    Points
    84
    Par défaut
    En effet c'est une syntaxe C++11, je pensais que quelque chose bloquait au niveau de l'initialisation ou de la portée tout du moins.

    J'ai réglé ça avec boost:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    const std::map<std::string, bool> DataPrimitive::_SPECFIELDS_WRITERULES = boost::assign::map_list_of
    	(struct_::DataModel::FIELD_RECORD, false)
    	(struct_::DataModel::FIELD_VERSION, false)
    	(struct_::DataModel::FIELD_OBJID, false)
    	(struct_::DataModel::FIELD_SECOWNERID, true)
    	(struct_::DataModel::FIELD_CREATETIME, false)
    	(struct_::DataModel::FIELD_UPDATETIME, false)
    	(struct_::DataModel::FIELD_MAKETIME, true)
    	(struct_::DataModel::FIELD_REMOVETIME, true)
    	(struct_::DataModel::FIELD_COLLECINDEX, false);
    Bonne soirée et merci pour les précisions.

  9. #9
    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 : 49
    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
    Points : 16 213
    Points
    16 213
    Par défaut
    Avec visual studio, la syntaxe est disponible (mais assez buggée) dans le version bêta nommée "november 2012 CTP" qui peut se télécharger sur le net. J'attends impatiemment qu'elle devienne officiellement supportée.

    Sinon, l'appel à une fonction virtuelle dans un constructeur est autorisée, il faut juste savoir que c'est la version du type en cours de construction que sera prise, pas la version du type final qu'aura l'objet quand il sera totalement construit.
    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.

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

Discussions similaires

  1. initialiser à vide une map static
    Par freestyler1982 dans le forum Collection et Stream
    Réponses: 11
    Dernier message: 25/09/2014, 10h38
  2. Réponses: 5
    Dernier message: 19/10/2010, 11h54
  3. initialiser un static map
    Par Plomeg dans le forum C++
    Réponses: 15
    Dernier message: 29/03/2008, 20h54
  4. [debutant] initialisation variable static
    Par julien.63 dans le forum Langage
    Réponses: 3
    Dernier message: 12/01/2008, 18h02
  5. std::map static
    Par oxor3 dans le forum SL & STL
    Réponses: 10
    Dernier message: 10/02/2006, 08h44

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