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 :

Liste d'initialisation et norme


Sujet :

C++

  1. #1
    Rédacteur
    Avatar de Bakura
    Homme Profil pro
    Étudiant
    Inscrit en
    Septembre 2005
    Messages
    1 386
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Septembre 2005
    Messages : 1 386
    Points : 2 640
    Points
    2 640
    Par défaut Liste d'initialisation et norme
    Bonsoir,

    Je souhaiterais savoir si la norme garantit que les variables initialisées dans une liste d'initialisation le soient avant celles du corps du constructeur ? (C'est à dire, si j'initialise une variable dans une liste d'initialisation du constructeur, et que je l'utilise par la suite dans le corps même du constructeur, est-ce que la norme me garantit que cette variable aura bien la valeur à laquelle je l'ai initialisée ?).

    Merci

  2. #2
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    29
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 29
    Points : 26
    Points
    26
    Par défaut
    Bonsoir,
    Oui elles sont initialisées avant d'entrer dans le corps du constructeur.
    De plus l'ordre d'initialisation est celui de la liste d'initialisation du constructeur et pas celui de leur declaration dans la classe.

  3. #3
    Rédacteur
    Avatar de Bakura
    Homme Profil pro
    Étudiant
    Inscrit en
    Septembre 2005
    Messages
    1 386
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Septembre 2005
    Messages : 1 386
    Points : 2 640
    Points
    2 640
    Par défaut
    D'accord merci

  4. #4
    Membre expérimenté
    Avatar de coyotte507
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    1 327
    Détails du profil
    Informations personnelles :
    Âge : 33
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 1 327
    Points : 1 452
    Points
    1 452
    Par défaut
    Citation Envoyé par fafacpp Voir le message
    De plus l'ordre d'initialisation est celui de la liste d'initialisation du constructeur et pas celui de leur declaration dans la classe.
    Tu es sûr?
    Quand sous minGW l'ordre n'est pas le même, il me sort un warning?

  5. #5
    Membre expert
    Avatar de Klaim
    Homme Profil pro
    Développeur de jeux vidéo
    Inscrit en
    Août 2004
    Messages
    1 717
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur de jeux vidéo
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 1 717
    Points : 3 344
    Points
    3 344
    Par défaut
    On m'a confirmé sur ce forum une fois que l'initialisation était uniquement dépendante de l'ordre de déclaration dans la classe...

    C'était a cause d'un problème de membres interdépendants de ce type :

    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
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    #include <iostream>
     
    class A
    {
    public:
    	A( int k ) : K( k ) {}
     
    	const int K;
    };
     
    class B
    {
    public:
    	B( const A& a) : m_a( a ) 
    	{
    		std::cout<< m_a.K <<std::endl;
    	}
     
    private:
    	const A& m_a;
    };
     
    class C
    {
    public:
     
    	C();
     
    private:
     
    	B m_b;
    	A m_a;
     
    };
     
    C::C()
    : m_b( m_a )
    , m_a( 42 )
    {
    }
     
    int main()
    {
    	C test;
     
    	std::cin.ignore(1);
    	return 0;
    }
    Après tests sous VC9, le programe affiche :
    Et en remplaçant juste :

    par
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
     
    	A m_a;
    	B m_b;
    On obtient le resultat voulu :

    Tout ça pour dire que l'ordre d'initialisation est toujours celui de déclaration dans la classe (et si c'est pas ça j'aimerai bien connaitre les exceptions O__O )

    EDIT> Oups, en relisant je me rends compte que c'est hors sujet... Désolé!!

  6. #6
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    29
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 29
    Points : 26
    Points
    26
    Par défaut
    Oups!
    Autant pour moi, c'est l'inverse de ce que j'ai dit : l'ordre d'initialisation des membres depent de l'ordre de declaration dans la classe et pas dans la liste d'nitialisation du constucteur.

  7. #7
    Expert éminent sénior
    Avatar de Luc Hermitte
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2003
    Messages
    5 275
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Août 2003
    Messages : 5 275
    Points : 10 985
    Points
    10 985
    Par défaut
    Tous les membres constructibles sont construits dans l'ordre de déclaration des membres.

    S'ils sont explicités dans la liste d'initialisation, ils seront construits (ou juste initialisés selon la nature du type ; tout en respectant toujours l'ordre de déclaration dans la classe) à l'aide des paramètres spécifiés.
    Blog|FAQ C++|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS|Bons livres sur le C++
    Les MP ne sont pas une hotline. Je ne réponds à aucune question technique par le biais de ce média. Et de toutes façons, ma BAL sur dvpz est pleine...

  8. #8
    Expert éminent

    Homme Profil pro
    Ingénieur systèmes et réseaux
    Inscrit en
    Février 2007
    Messages
    4 253
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur systèmes et réseaux
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Février 2007
    Messages : 4 253
    Points : 7 618
    Points
    7 618
    Billets dans le blog
    3
    Par défaut
    Et c'est aussi valable pour les classes parentes (en cas d'héritage multiple). C'est l'ordre d'apparition des éléments qui induit l'ordre de construction/initialisation.
    N'oubliez pas de cliquer sur mais aussi sur si un commentaire vous a été utile !
    Et surtout

  9. #9
    Rédacteur
    Avatar de Bakura
    Homme Profil pro
    Étudiant
    Inscrit en
    Septembre 2005
    Messages
    1 386
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Septembre 2005
    Messages : 1 386
    Points : 2 640
    Points
    2 640
    Par défaut
    Citation Envoyé par Luc Hermitte Voir le message
    Tous les membres constructibles sont construits dans l'ordre de déclaration des membres.

    S'ils sont explicités dans la liste d'initialisation, ils seront construits (ou juste initialisés selon la nature du type ; tout en respectant toujours l'ordre de déclaration dans la classe) à l'aide des paramètres spécifiés.
    Donc... C'est en contradiction avec ce qu'à dis fafacpp dans le premier post ?

    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
     
    Imagine cette classe :
     
    class A
    {
    public:
       A (int v)
          : truc (v)
      {
          bidule = truc * 2;
      }
     
    int bidule;
    int truc;
    };
    Si j'en crois ton post, lorsque je ferai bidule = truc * 2, truc ne sera pas initialisée avec la variable v puisque dans la déclaration bidule est déclaré avant truc ?

    C'est ça que je voulais savoir... !

  10. #10
    Expert éminent sénior
    Avatar de Luc Hermitte
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2003
    Messages
    5 275
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Août 2003
    Messages : 5 275
    Points : 10 985
    Points
    10 985
    Par défaut
    Il s'est rétracté pour son premier post qui était effectivement faut.

    Et ici, tu confonds corps avec liste d'initialisation.
    Blog|FAQ C++|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS|Bons livres sur le C++
    Les MP ne sont pas une hotline. Je ne réponds à aucune question technique par le biais de ce média. Et de toutes façons, ma BAL sur dvpz est pleine...

  11. #11
    Rédacteur
    Avatar de Bakura
    Homme Profil pro
    Étudiant
    Inscrit en
    Septembre 2005
    Messages
    1 386
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Septembre 2005
    Messages : 1 386
    Points : 2 640
    Points
    2 640
    Par défaut
    Et ici, tu confonds corps avec liste d'initialisation.
    Ben je sais pas, tout ce que je veux savoir c'est, si sur mon exemple, les variables initialisées dans la liste d'initialisation le sont avec celles du corps du constructeur.

    Pour l'instant je comprends : d'abord liste d'initialisation, et dans la liste d'initalisation, elles sont initialisées suivant l'ordre de déclaration. C'est ça ?

  12. #12
    Expert éminent sénior
    Avatar de Luc Hermitte
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2003
    Messages
    5 275
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Août 2003
    Messages : 5 275
    Points : 10 985
    Points
    10 985
    Par défaut
    Le corps c'est à la fin.

    L'ordre c'est celui des déclarations, et avec constructions par défaut même si rien n'est dit dans la liste d'initialisation (j'essaie de reformuler autrement)
    Blog|FAQ C++|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS|Bons livres sur le C++
    Les MP ne sont pas une hotline. Je ne réponds à aucune question technique par le biais de ce média. Et de toutes façons, ma BAL sur dvpz est pleine...

  13. #13
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    29
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 29
    Points : 26
    Points
    26
    Par défaut
    Quelques exemples valent souvent plus qu'un long discours:

    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 A
    {
    	public:
    		A()
    		: mX(10), mY(20)
    		{
    		    ;
    		}
     
    		~A() {}
    	protected:
     
    	private:
            int mX;
            int mY;
     
    };
    Dans ce cas pas de problème, l'ordre est le même dans la declaration et l'initialisation. Les valeurs des membres dans le corps (entre les {}) sont bien
    mX=10 et mX=20.

    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 A
    {
    	public:
    		A()
    		: mY(10), mX(20)
    		{
    		    ;
    		}
     
    		~A() {}
    	protected:
     
    	private:
            int mX;
            int mY;
     
    };
    Dans ce cas pas de problème non plus, l'ordre n'est pas le même dans la declaration et l'initialisation, mais ca n'a pas d'incidence. Les valeurs des membres dans le corps (entre les {}) sont bien
    mX=10 et mX=20. Le compilo renvoi un warning pour indiquer que l'ordre est different (MinGW).

    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 A
    {
    	public:
    		A()
    		: mX(10), mY(mX*2)
    		{
    		    ;
    		}
     
    		~A() {}
    	protected:
     
    	private:
            int mX;
            int mY;
     
    };
    Dans cet exemple, l'initialisation d'un membre dépend de la valeur d'un autre membre, l'ordre d'initialisation devient primordial, ici l'ordre de declaration et l'ordre d'initialisation sont les même, mX sera bien initialisé à 10 AVANT mY et mY sera ensuite initialisé à 20 (2*mX).Les valeurs des membres dans le corps (entre les {}) sont toujours mX=10 et mX=20.

    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 A
    {
    	public:
    		A()
    		: mY(20), mX(2*mY)
    		{
    		    ;
    		}
     
    		~A() {}
    	protected:
     
    	private:
            int mX;
            int mY;
     
    };
    Et là c'est le drame, l'initialisation d'un membre dépend de la valeur d'un autre membre, ici l'ordre de declaration et l'ordre d'initialisation ne sont pas les même, mX sera initialisé à 2*mY AVANT que mY ne soit initialisé et sa valeur sera indeterminée (aucune chance que mX=40) , mY sera ensuite initialisé à 20.Les valeurs des membres dans le corps (entre les {}) sont cette fois mX=? et mX=20.
    Le compilo renvoi un warning pour indiquer que l'ordre est different (MinGW).

    Ce qui est trompeur c'est qu'en lisant la liste d'initialisation du constructeur, on pourrait penser que mY est initialisé avant mX, c'est faux : L'ORDRE D'INITIALISATION DEPEND UNIQUEMENT DE L'ORDRE DE DECLARATION DANS LA CLASSE. Ceci dit le problème d'ordre d'initialisation ne se pose que quand l'initialisation d'un membre est fonction de la valeur d'un autre membre.

    En espérant que c'est un peu plus clair, et que j'ai pas trop dit de bétises.

  14. #14
    Expert éminent sénior
    Avatar de Luc Hermitte
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2003
    Messages
    5 275
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Août 2003
    Messages : 5 275
    Points : 10 985
    Points
    10 985
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    struct Foo {
       Foo() : m_x(m_bar.getX()) {}
    private:
     
    #if defined(COMME_CA_CA_MARCHE)
       Bar m_bar;
       int m_x;
    #else
       int m_y;
       Bar m_bar;
    #endif
    };
    Bar disposant d'un constructeur par défaut initialisant son x à lui.
    Blog|FAQ C++|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS|Bons livres sur le C++
    Les MP ne sont pas une hotline. Je ne réponds à aucune question technique par le biais de ce média. Et de toutes façons, ma BAL sur dvpz est pleine...

  15. #15
    Membre expérimenté
    Avatar de coyotte507
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    1 327
    Détails du profil
    Informations personnelles :
    Âge : 33
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 1 327
    Points : 1 452
    Points
    1 452
    Par défaut
    Citation Envoyé par Bakura Voir le message
    Ben je sais pas, tout ce que je veux savoir c'est, si sur mon exemple, les variables initialisées dans la liste d'initialisation le sont avec celles du corps du constructeur.

    Pour l'instant je comprends : d'abord liste d'initialisation, et dans la liste d'initalisation, elles sont initialisées suivant l'ordre de déclaration. C'est ça ?
    Oui, bien sûr, les variables de la liste d'initialisation sont initialisée en même temps que l'objet est crée, c'est à dire avant le corps du constructeur.

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

Discussions similaires

  1. Liste d'initialisation en java ?
    Par jph_void dans le forum Langage
    Réponses: 12
    Dernier message: 13/05/2008, 10h44
  2. Réponses: 4
    Dernier message: 20/04/2008, 21h12
  3. Liste d'initialisation C++
    Par three minute hero dans le forum BOUML
    Réponses: 7
    Dernier message: 08/10/2007, 11h18
  4. FAQ -> liste d'initialisation
    Par Mindiell dans le forum C++
    Réponses: 24
    Dernier message: 05/09/2007, 18h24
  5. [syntax] liste d'initialisation et heritage
    Par ZaaN dans le forum C++
    Réponses: 1
    Dernier message: 12/12/2006, 17h01

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