Bonjour,
je voulais savoir si on pouvait utiliser sans danger des fonctions virtuelles dans les constructeurs ? Y a-t-il des problèmes avec le "niveau" d'abstraction ?
merci :)
Version imprimable
Bonjour,
je voulais savoir si on pouvait utiliser sans danger des fonctions virtuelles dans les constructeurs ? Y a-t-il des problèmes avec le "niveau" d'abstraction ?
merci :)
Le résultat de ce code répondra à ta question.Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 #include <iostream> struct A { A() { foo(); } virtual void foo() { std::cout << "A::foo" << std::endl; } }; struct B : A { virtual void foo() { std::cout << "B::foo" << std::endl; } }; int main() { B b; }
Je connais la réponse, je l'ai lu hier et l'avais testé également pour vérifier ^^ :mouarf:
D'après ce que j'ai compris, une fonction virtuelle possède une v-table (table virtuelle) qui contient des pointeurs de fonctions vers les versions contenues dans les classes filles. La classe virtuelle sait laquelle choisir. Mais après je ne sais pas exactement comment ça marche, je suis bien curieux !
:roll:
Salut,
Ce qui se passe, c'est que pour que pouvoir considérer que le contenu d'une classe dérivée est accessible, il faut attendre de se trouver après la liste d'initialisation (ou, si tu préfères, entre les deux accolades qui définissent le constructeur).
Or, la classe de base est la toute première chose qui est initialisée.
Il s'en suit que, lorsque tu te trouve dans le constructeur de la classe de base, la seule chose qui soit accessible, ce sont les membres (et les fonctions membres) de... la classe de base ;)
Merci, je dormirai moins bête ce soir ;)
Je trouve passionnant de connaître ce genre de détails ! :king:
J'aime bien savoir comment les choses fonctionnent !
Un truc à savoir: Ce n'est pas le cas en .Net.
J'avais lu un bon article quelque part là-dessus, mais impossible de le retrouver. Aussi, le lien était peut-être posté sur le forum, mais je n'en suis pas sûr...
Enfin, en attendant, j'ai toujours trouvé ça:
http://www.artima.com/cppsource/pure_virtual.html
Ce n'est pas un probleme d'accessibilite (ce qui en C++ designe les protections introduites par public/protected/private) mais un probleme de type dynamique.
Durant l'execution des constructeurs (et des destructeurs), le type dynamique est le type du constructeur (ou du destructeur) en cours d'execution.
Un avantage est que cela evite de d'acceder a des membres non encore construits de la classe descendante. Si dans
c'etait D::foo() qui etait execute, s ne serait pas encore construit avec tous les problemes qu'on imagine.Code:
1
2
3
4
5
6
7
8
9 struct S { S() { foo(); } virtual void foo() {} }; struct D: S { void foo() { s = "D"; } string s; };
Interressant tout ça.
Je suis en train de me documenter sur le mécanisme des fonctions virtuelles avec les v-table/v-pointeur, RTTI, ...
C'est en comprenant les mécanismes internes qu'on peut mieux programmer et éventuellement éviter certains bugs :)
http://ldeniau.web.cern.ch/ldeniau/html/oopc.html, tout en bas: C++ Object Model.
Never call virtual functions during construction or destruction. (Scott Meyers).
En fait, à mon avis c'est aussi lié à la compréhension de ce qui se passe pendant la construction d'un objet, et en particulier de l'ordre dans lequel les objets sont construits. J'avais fait une réponse, mais j'arrive pas à trouver un articule plus précis.