2010-02-11 11 views
4

C'est un problème que je rencontre souvent. Les exemples suivants illustrent le:Initialisation de membres avec des membres

struct A { 
    int m_SomeNumber; 
}; 

struct B { 
    B(A & RequiredObject); 
private: 
    A & m_RequiredObject; 
}; 

struct C { 
    C(); 
private: 
    A m_ObjectA; 
    B m_ObjectB; 
}; 

La mise en œuvre du constructeur de C ressemble à quelque chose comme ceci:

C::C() 
: B(m_ObjectA) 
{ } 

Depuis l'ordre d'initialisation n'est pas définie, m_ObjectA peut être non initialisée lorsque le constructeur de m_ObjectB est appelé, ce qui entraîne un comportement indéfini. Une façon de forcer un certain ordre d'initialisation serait de faire pointer les membres et de les initialiser dans le corps du constructeur, forçant ainsi l'ordre correct, mais c'est moche pour plusieurs raisons. Est-il possible de forcer un certain ordre d'initialisation en utilisant la liste d'initialisation du constructeur? Si non, avez-vous d'autres suggestions sur la façon de gérer cela.

Répondre

12

Depuis l'ordre d'initialisation n'est pas définie

Au contraire, il est bien défini. L'ordre d'initialisation est égal à l'ordre dans lequel les variables membres sont déclarées dans votre classe (indépendamment de l'ordre réel de la liste d'initialisation!) Il est donc judicieux de laisser l'ordre de la liste d'initialisation correspondre à l'ordre des déclarations. éviter les mauvaises surprises).

+0

bien, je pensais autrement. Merci pour la réponse rapide! –

+1

J'ajouterais que c'est assez fragile, car votre confiance en la commande peut être non évidente pour le lecteur. Donc au moins j'ajouterais un commentaire à la définition de m_objectB à l'effet de "doit être défini après m_objectA". – peterchen

+0

@peterchen: c'est pourquoi l'ordre de la liste d'initialisation doit correspondre à l'ordre de déclaration. –