Chaîne de constructeurs en C ++

D’après ce que je comprends du chaînage des constructeurs, lorsqu’il y a plusieurs constructeurs dans une classe (constructeurs surchargés), si l’un d’entre eux tente d’appeler un autre constructeur, ce processus s’appelle CONSTRUCTOR CHAINING, ce qui n’est pas pris en charge en C ++. Récemment, je suis tombé sur ce paragraphe en lisant des documents en ligne … Cela va comme ça …

Vous pouvez vous trouver dans la situation où vous souhaitez écrire une fonction membre pour réinitialiser une classe aux valeurs par défaut. Parce que vous avez probablement déjà un constructeur qui fait cela, vous pouvez être tenté d’appeler le constructeur à partir de votre fonction membre. Comme mentionné précédemment, les appels de constructeur de chaînes sont illégaux en C ++. Vous pouvez copier le code du constructeur dans votre fonction, ce qui fonctionnerait, mais conduirait à un code dupliqué. La meilleure solution dans ce cas consiste à déplacer le code du constructeur vers votre nouvelle fonction et à ce que le constructeur appelle votre fonction pour effectuer le travail d’initialisation des données.

Une fonction membre appelant le constructeur est-elle également associée au chaînage des constructeurs? Veuillez jeter un peu de lumière sur ce sujet en C ++.

Le paragraphe dit essentiellement ceci:

class X { void Init(params) {/*common initing code here*/ } X(params1) { Init(someParams); /*custom code*/ } X(params2) { Init(someOtherParams); /*custom code*/ } }; 

Vous ne pouvez pas non plus appeler un constructeur depuis une fonction membre. Il peut vous sembler que vous l’avez fait, mais c’est une illusion:

 class X { public: X(int i):i(i){} void f() { X(3); //this just creates a temprorary - doesn't call the ctor on this instance } int i; }; int main() { using std::cout; X x(4); cout << xi << "\n"; //prints 4 xf(); cout << xi << "\n"; //prints 4 again } 

C ++ 11 permet l’enchaînement des constructeurs (partiellement). Cette fonctionnalité est appelée ” délégation de constructeurs “. Donc, en C ++ 11, vous pouvez faire ce qui suit

 class Foo { public: Foo(int a) : Foo() { _a = a; } Foo(char* b) : Foo() { _b = b; } Foo() { _c = 1.5; } private: int _a = 0; char* _b = nullptr; double _c; }; 

Cependant, le constructeur qui appelle un autre constructeur n’est pas autorisé à initialiser d’autres membres. Vous ne pouvez donc pas effectuer les opérations suivantes avec un constructeur délégué:

 class Foo { public: Foo(int a) : Foo(), _a(a) { } Foo(char* b) : Foo(), _b(b) { } Foo() { _c = 1.5; } private: int _a = 0; char* _b = nullptr; double _c; }; 

MSVC ++ 2013 donne l’erreur de compilation “C3511: un appel à un constructeur de délégation doit être le seul initialisateur de membre” pour le dernier exemple de code.

Ce n’est pas ce que dit le texte. Cela suggère que votre constructeur appelle une fonction membre qui est normale et légale. Cela évite de rappeler explicitement le ctor et d’éviter la duplication de code entre votre ctor et la fonction de réinitialisation.

 Foo::Foo() { Init(); } void Foo::Reset() { Init(); } void Foo::Init() { // ... do stuff ... } 

Je ne sais pas si cela (appeler un constructeur à partir d’une fonction membre) fonctionnera ou non, mais c’est une mauvaise pratique. déplacer le code d’initialisation vers une nouvelle fonction est la voie logique.

En gros, dites, n’appelez pas le constructeur à moins que vous ne construisiez …

Lorsque nous appelons le constructeur à partir d’une fonction membre, il crée temporairement un object de ce type. si nous appelons une fonction de classe dérivée, tous les constructeurs parents sont également exécutés et détruits à l’aide de destructor une fois que la fonction est hors de scope.

ce n’est pas une bonne pratique d’appeler les constructeurs dans les fonctions membres car il crée des objects de chaque classe dérivée.