Question

J'ai quelques doutes sur les garanties d'ordre et la construction d'initialisation en C ++. Par exemple, le code suivant a quatre classes X, Y, Z et W. La fonction principale instancie un objet de class X, qui contient un objet de class Y et dérive de class Z, afin que les deux constructeurs seront appelés. En outre, le paramètre const char* passé au constructeur de X sera implicitement convertie à un objet de class W, de sorte que le constructeur de W doit également être appelé.

Quelles sont les garanties de la norme C donne de l'ordre des appels aux constructeurs de copie? Ou, ce qui revient, ce que ce programme est autorisé à imprimer?

#include <iostream>

class Z {
   public:
   Z() { std::cout << "Z" << std::endl; }
};

class Y {
   public:
   Y() { std::cout << "Y" << std::endl; }
};

class W {
   public:
   W(const char*) { std::cout << "W" << std::endl; }
};

class X : public Z {
   public:
   X(const W&) { std::cout << "X" << std::endl; }
   private:
   Y y;
};

int main(int, char*[]) {
   X x("x");
   return 0;
}

modifier: Est-ce exact

   W      |
 /   \    |
Z     Y   |
 \   /    |
   X      V
Était-ce utile?

La solution

Dans l'ordre de construction classes est garanti: les classes de base, comme indiqué de gauche à droite suivi par des variables membres dans l'ordre déclaré dans la définition de la classe. est exécuté une fois que toutes ses bases et des membres de constructions ont terminé les corps de constructeur d'une classe.

Dans votre exemple X est dérivé d'Z et contient Y si l'objet de base de Z est réalisé en premier, puis l'élément de Y y, alors la construction de la X complète avec l'exécution du corps du constructeur de X.

Le W temporaire est nécessaire pour passer au constructeur de X, il est donc construit avant la construction du x commence et sera détruite une fois l'initialisation de x complète.

Ainsi, le programme doit imprimer:

W
Z
Y
X

Autres conseils

1) Tout d'abord, il est nécessaire de calculer les arguments.

2) Ensuite, les classes de base sont construits.

3) Ensuite, les membres sont construits dans l'ordre d'apparition dans la déclaration de la classe.

4) Ensuite Constructor de X est appelé

  1. L'objet W sera construit avant que le constructeur de X est appelée.
  2. Z, en tant que classe de base de X, sera initialisé avant que les membres de X.
  3. Y sera initalized lors de l'initialisation du membre
  4. constructeur de X fonctionnera.

Pour développer la réponse de Charles Bailey, les règles changent lorsque vos classes de base sont pratiquement héritées. J'oublie toujours ce que l'ordre est, le site IBM dit que les bases virtuelles sont initialisés première mais j'ai jamais courir dans un cas où il est en fait plus trivia.

Pour résumer ce sont les règles:

  1. Arguments, prises de droite à gauche
     une. Droit le plus
     b. 2e à droite
  2. Classe de base
  3. Base virtuelle
  4. Les classes de base de gauche à droite
  5. Membres dans l'ordre de déclaration en classe
  6. Constructeur de classe appelée
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top