2010-08-23 6 views
34

Je ne suis pas sûr d'un bon moyen d'initialiser un shared_ptr qui est membre d'une classe. Pouvez-vous me dire, si la façon dont je choisis dans C::foo() est bien, ou y at-il une meilleure solution?Comment initialiser un shared_ptr membre d'une classe?

class A 
{ 
    public: 
    A(); 
}; 

class B 
{ 
    public: 
    B(A* pa); 
}; 

class C 
{ 
    boost::shared_ptr<A> mA; 
    boost::shared_ptr<B> mB; 
    void foo(); 
}; 

void C::foo() 
{ 
    A* pa = new A; 
    mA = boost::shared_ptr<A>(pa); 
    B* pB = new B(pa); 
    mB = boost::shared_ptr<B>(pb); 
} 
+2

Utilisez les listes d'initialisation. – Chubsdad

+0

chubsdad: Ne fonctionne pas dans les membres, seulement dans les ctors. – MSalters

+0

@MSalters: Je n'ai aucune idée de ce que vous essayez de dire. – sbi

Répondre

30

Votre code est tout à fait correct (cela fonctionne), mais vous pouvez utiliser la liste d'initialisation, comme ceci:

C::C() : 
    mA(new A), 
    mB(new B(mA.get()) 
{ 
} 

Ce qui est encore plus correct et aussi sûr.

Si, pour une raison quelconque, new A ou new B jette, vous n'aurez aucune fuite.

Si new A se déclenche, aucune mémoire n'est allouée et l'exception annule également votre constructeur. Rien n'a été construit.

Si new B se déclenche, l'exception interrompra toujours votre constructeur: mA sera détruit correctement.

Bien sûr, étant donné qu'une instance de B nécessite un pointeur vers une instance de A, l'ordre de déclaration des membres importe.

L'ordre de déclaration de membre est correct dans votre exemple, mais si elle a été renversée, votre compilateur se plaindraient probablement à mB beeing initialisés avant mA et l'instanciation de mB échouerait probablement (puisque mA ne serait pas construit encore, ainsi appeler mA.get() invoque un comportement indéfini).


Je suggère également que vous utilisez un shared_ptr<A> au lieu d'un A* comme paramètre pour votre B constructeur (si il fait sens et si vous pouvez accepter le peu de frais généraux). Ce serait probablement plus sûr.

Peut-être est-il garanti qu'une instance de B ne peut pas vivre sans une instance de A et alors mon conseil ne s'applique pas, mais nous manquons de contexte ici pour donner un avis définitif à ce sujet.

+1

Étant donné que vous comptez sur elle, il est utile de parler de la façon dont l'ordre de construction des membres fonctionne et les points de séquence impliqués. –

+0

@ereOn - Un type de retour pour un constructeur? – DumbCoder

+0

@DumbCoder: Copié de la question où c'est aussi faux. Je l'ai corrigé. – sbi

Questions connexes