Enchaînement des constructeurs en C++

ma compréhension de l'enchaînement des constructeurs est que, lorsqu'il y a plus d'un constructeur dans une classe (constructeurs surchargés) , si l'un d'eux essaie d'appeler un autre constructeur,alors ce processus s'appelle le chaînage de constructeur , qui n'est pas supporté en C++ . Récemment, je suis tombé sur ce paragraphe en lisant des documents en ligne.... Il va comme ceci ...

Vous pouvez vous trouver dans la situation où vous voulez écrire une fonction membre de ré-initialiser une retour en classe pour les valeurs par défaut. Parce que vous avez probablement déjà un constructeur qui fait cela, vous pourriez être tenté d'essayer d'appeler le constructeur de votre fonction membre. Comme mentionné, enchaîner les appels des constructeurs est illégal en C++. Vous pouvez copier le code du constructeur dans votre fonction, ce qui fonctionnerait, mais conduirait à dupliquer le code. La meilleure solution dans ce cas est de déplacer le code du constructeur vers votre nouvelle fonction, et que le constructeur appelle votre fonction pour faire le travail de initialisation des données.

est-ce qu'une fonction membre appelant le constructeur relève également du chaînage constructeur ?? S'il vous plaît, éclairez ce sujet en C++ .

28
demandé sur Paul Sweatte 2011-09-08 17:54:32

5 réponses

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 appeler un constructeur à partir d'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 << x.i << "\n"; //prints 4
    x.f();
    cout << x.i << "\n"; //prints 4 again
}
18
répondu Armen Tsirunyan 2013-08-19 13:15:04

C++11 permet le chaînage du constructeur (partiellement). Cette fonctionnalité est appelée "déléguant 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, il y a une limitation importante qu'un constructeur qui appelle un autre constructeur n'est pas autorisé à initialiser d'autres membres. Vous ne pouvez donc pas faire ce qui suit avec un constructeur qui délègue:

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 une erreur de compilation " C3511: un appel à un constructeur délégant doit être seuls les membres de l'initialiseur" pour le dernier exemple de code.

17
répondu Serge Rogatch 2015-10-22 07:10:30

ce n'est pas ce que le texte dit. Cela suggère que votre constructeur appelle une fonction de membre qui est normale et légale. Ceci pour éviter d'appeler explicitement le ctor à nouveau et pour éviter de dupliquer le code entre votre ctor et la fonction de réinitialisation.

Foo::Foo() {
  Init();
}

void Foo::Reset() {
  Init();
}

void Foo::Init() {
  // ... do stuff ...
}
3
répondu i_am_jorf 2011-09-08 13:58:56

Je ne suis pas sûr que cela (appeler un constructeur à partir d'une fonction membre) fonctionne ou non, mais c'est une mauvaise pratique. déplacer le code initialize vers une nouvelle fonction est la manière logique.

essentiellement en disant, Ne pas appeler le constructeur à moins que vous construisez...

0
répondu Roee Gavirel 2011-09-08 14:00:37

quand nous appelons le constructeur à partir d'une fonction membre, alors il créera temporairement un objet de son type. dans le cas où nous appelons dans la fonction de classe dérivée, alors tous les constructeurs parents sont aussi exécutés et détruits en utilisant destructor une fois que la fonction sort de la portée.

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

0
répondu Narayan 2013-11-16 01:34:57