39 votes

Est-il possible d'appeler une fonction dans la liste d'initialisation du constructeur ?

Mon intuition me dit que ce n'est pas le cas. Je me trouve dans la situation suivante :

class PluginLoader
{
   public:
      Builder* const p_Builder;
      Logger* const p_Logger;

      //Others
};

PluginLoader::PluginLoader(Builder* const pBuilder)
   :p_Builder(pBuilder), p_Logger(pBuilder->GetLogger())
{
   //Stuff
}

Ou dois-je changer le constructeur et passer un Logger* const d'où PluginLoader est construit ?

41voto

GManNickG Points 155079

C'est parfaitement bien et normal. p_Builder a été initialisée avant elle.

33voto

Benjamin Lindley Points 51005

Ce que vous avez est très bien. Cependant, je veux juste vous avertir d'être prudent. de ne pas le faire (GMan y a fait allusion, je voulais juste que ce soit parfaitement clair).

class PluginLoader
{
   public:
      Logger* const p_Logger;   // p_Logger is listed first before p_Builder
      Builder* const p_Builder;

      //Others
};

PluginLoader::PluginLoader(Builder* const pBuilder)
   :p_Builder(pBuilder),
    p_Logger(p_Builder->GetLogger())   // Though listed 2nd, it is called first.
                                       // This wouldn't be a problem if pBuilder 
                                       // was used instead of p_Builder
{
   //Stuff
}

Notez que j'ai apporté 2 modifications à votre code. Premièrement, dans la définition de la classe, j'ai déclaré p_Logger avant p_Builder. Deuxièmement, j'ai utilisé le membre p_Builder pour initialiser p_Logger, au lieu du paramètre.

L'un ou l'autre de ces changements serait correct, mais ensemble, ils introduisent un bogue, car p_Logger est initialisé en premier, et vous utilisez le p_Builder non initialisé pour l'initialiser.

N'oubliez jamais que les membres sont initialisés dans l'ordre où ils apparaissent dans la définition de la classe. Et l'ordre dans lequel vous les placez dans votre liste d'initialisation n'a aucune importance.

1voto

Jason Rogers Points 8924

C'est une très bonne pratique.

Je vous suggère ceci (mais c'est à titre purement personnel) :

au lieu d'avoir des fonctions appelées dans votre constructeur, de les regrouper dans une fonction init, uniquement à des fins de flexibilité : si vous devez créer d'autres constructeurs par la suite.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X