Ordre des constructeurs et destructeurs C ++

J’essaie un code sur la construction et la destruction de classes de base et de membres et je suis confus quant à un certain ordre de constucteur et de destructeur, la sortie de ce code est:

Base1 constructor Member1 constructor Member2 constructor Derived1 constructor Member3 constructor Member4 constructor Derived2 constructor Derived2 destructor Member4 destructor Member3 destructor Derived1 destructor Member2 destructor Member1 destructor Base1 destructor 

Voir les quatre premières lignes, mais je suis tombé l’ordre devrait être

 Base1 constructor Derived1 constructor Member1 constructor Member2 constructor 

Tout le monde peut me donner des explications

 #include "stdafx.h" #include  using namespace std; ofstream out("order.out"); #define CLASS(ID) class ID { \ public: \ ID(int) { out << #ID " constructor\n"; } \ ~ID() { out << #ID " destructor\n"; } \ }; CLASS(Base1); CLASS(Member1); CLASS(Member2); CLASS(Member3); CLASS(Member4); class Derived1 : public Base1 { Member1 m1; Member2 m2; public: Derived1(int) : m2(1), m1(2), Base1(3) { out << "Derived1 constructor\n"; } ~Derived1() { out << "Derived1 destructor\n"; } }; class Derived2 : public Derived1 { Member3 m3; Member4 m4; public: Derived2() : m3(1), Derived1(2), m4(3) { out << "Derived2 constructor\n"; } ~Derived2() { out << "Derived2 destructor\n"; } }; int main() { Derived2 d2; } ///:~ 

Les constructeurs sont appelés ascendants dans la hiérarchie:

 - base class member objects - base class constructor body - derived class member objects - derived class constructor body 

La sortie est correcte.

Simplifions votre code:

 struct BaseMember { BaseMember() { cout << "base member" < 

Lorsque d est créé, il crée d’abord la partie Base . Avant d'entrer dans le corps du constructeur, tous les objects membres sont initialisés. Donc, BaseMember est le premier object initialisé.

Ensuite, le constructeur de Base est entré.

Avant, le constructeur d' Derived , les objects membres de Derived sont initialisés. Par conséquent, DerivedMember est créé, puis le constructeur Derived suivant est appelé.

Cela est dû au fait que lorsque vous entrez dans le corps du constructeur d'une classe dérivée, les classes de base et les objects membres doivent être complètement initialisés.

EDIT Comme Matthieu l'a fait remarquer, l'ordre dans lequel les objects membres sont initialisés est spécifié par l'ordre dans lequel ils apparaissent dans la définition de la classe, et non dans l'ordre dans lequel ils apparaissent dans la liste des initialiseurs.

Le constructeur de la classe s’exécute plus tard que les constructeurs de ses champs. Le constructeur de la classe de base et de tous ses membres s’exécute plus tôt que le constructeur de la classe dérivée et de ses membres.

En effet, m1 et m2 sont initialisés dans la liste d’initialisation du constructeur Derived1 . Tout dans la liste d’initialisation est construit avant que le corps du constructeur soit entré.

L’initialisation effectuée dans la liste d’initialisation se produit avant le corps du constructeur Derived1, de sorte que vous voyez d’abord la sortie pour m1 et m2.

Comme réponse plus complète, voici ce qui se produit: les premiers sous-objects de base sont construits, puis les membres sont construits dans l’ordre de leur déclaration dans la classe (et non dans la liste d’initialisation), puis le corps du constructeur est exécuté. La destruction se produit dans l’ordre inverse.

Dans ce cas, lorsque vous construisez un Derived2, il commence par construire le sous-object Derived1. Cela implique à son tour de construire d’abord le sous-object Base, c’est pourquoi il le fait en premier. Il construit ensuite les membres de Derived1, exécute le corps du constructeur Derived1, construit les membres de Derived2 et exécute le corps du constructeur Derived2. D’où le rendement observé.

Considérez le programme suivant qui rendra votre idée claire!

 #include class A { public: A() { cout<<"\nI am the base class constructor!"; } ~A() { cout<<"\nI am the base class destructor!"; } }; class B : public A { public: B() { cout<<"\nI am the derived class constructor!"; } ~B() { cout<<"\nI am the derived class destructor!"; } }; int main() { B obj; return 0; } 

La sortie du programme ci-dessus sera comme suit.

Je suis le constructeur de la classe de base!

Je suis le constructeur de la classe dérivée!

Je suis le destructeur de classe dérivé!

Je suis le destructeur de la classe de base!

Je pense que cela explique et clarifie votre question sur l’ordre d’invocation des constructeurs et des destructeurs.