web-dev-qa-db-fra.com

Pourquoi le constructeur par défaut est-il appelé en héritage virtuel?

Je ne comprends pas pourquoi dans le code suivant, lorsque j'instancie un objet de type daughter, le constructeur par défaut grandmother() est appelé?

J'ai pensé que soit le constructeur grandmother(int) devrait être appelé (pour suivre les spécifications de mon constructeur de classe mother), soit ce code ne devrait pas du tout compiler à cause de l'héritage virtuel.

Ici, le compilateur appelle silencieusement grandmother constructeur par défaut dans mon dos, alors que je ne l'ai jamais demandé.

#include <iostream>

class grandmother {
public:
    grandmother() {
        std::cout << "grandmother (default)" << std::endl;
    }
    grandmother(int attr) {
        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);
}
74
Simon Desfarges

Lors de l'utilisation de l'héritage virtuel, le constructeur de la classe de base virtuelle est appelé directement par le constructeur de la classe la plus dérivée. Dans ce cas, le constructeur daughter appelle directement le constructeur grandmother.

Puisque vous n'avez pas appelé explicitement le constructeur grandmother dans la liste d'initialisation, le constructeur par défaut sera appelé. Pour appeler le constructeur correct, changez-le en:

daugther(int attr) : grandmother(attr), mother(attr) { ... }

Voir aussi This FAQ entry .

76
interjay