Héritage virtuel et invocation du constructeur par défaut
Dans une hiérarchie d'héritage impliquant l'héritage virtuel, le constructeur par défaut de la classe de base virtuelle peut être appelé de manière inattendue . Considérons le code suivant :
class grandmother { public: grandmother() { // Default constructor std::cout << "grandmother (default)" << std::endl; } grandmother(int attr) { // Parameterized constructor std::cout << "grandmother: " << attr << std::endl; } }; class mother: virtual public grandmother { public: mother(int attr) : grandmother(attr) { std::cout << "mother: " << attr << std::endl; } }; class daughter: virtual public mother { public: daughter(int attr) : mother(attr) { std::cout << "daughter: " << attr << std::endl; } }; int main() { daughter x(0); }
Lorsqu'une instance de la classe fille est créée, le résultat est :
grandmother (default) mother: 0 daughter: 0
Malgré l'existence d'un constructeur paramétré dans la classe grand-mère, le le constructeur par défaut est invoqué. Pourquoi cela se produit-il ?
Invocation du constructeur de classe de base virtuelle
Dans l'héritage virtuel, le constructeur de la classe de base virtuelle est directement appelé par le constructeur de la classe la plus dérivée. Dans ce cas, le constructeur fille appelle directement le constructeur grand-mère.
Étant donné que la classe mère n'appelle pas explicitement le constructeur grand-mère dans sa liste d'initialisation, le constructeur par défaut est utilisé. Pour invoquer correctement le constructeur souhaité, le constructeur fille doit être modifié en :
daughter(int attr) : grandmother(attr), mother(attr) { ... }
En appelant explicitement le constructeur grand-mère (attr) dans la liste d'initialisation, le constructeur correct est utilisé et le résultat devient :
grandmother: 0 mother: 0 daughter: 0
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!