Pourquoi les fonctions virtuelles C invoquées par les constructeurs peuvent se comporter de manière inattendue
En C, les fonctions virtuelles fournissent une liaison dynamique, permettant à une classe dérivée de remplacer un fonction définie dans sa classe de base. Cependant, invoquer une fonction virtuelle à partir d'un constructeur peut conduire à des résultats inattendus.
Considérez l'extrait de code suivant :
#include <iostream> struct base { virtual const int value() const { return 0; } base() { std::cout << value() << std::endl; } virtual ~base() {} }; struct derived : public base { virtual const int value() const { return 1; } }; int main(void) { derived example; }
Le code définit deux classes, de base et dérivée, avec une fonction virtuelle valeur(). Le constructeur de base appelle value() lors de l'initialisation de l'objet. On pourrait s'attendre à ce que le code affiche "1" lors de son exécution, car l'objet de type dérivé est en cours de construction. Cependant, il renvoie "0" à la place.
La raison de ce comportement réside dans l'ordre de construction des objets. Lors de l'initialisation d'un objet de type dérivé, le constructeur de la classe de base est appelé en premier. À ce stade, l’objet n’est pas encore complètement initialisé et ses données membres spécifiques à la classe dérivée peuvent ne pas être initialisées. Par conséquent, l'appel de value() à partir du constructeur de base invoque l'implémentation de la classe de base de la fonction, qui renvoie 0.
Pour obtenir le comportement souhaité, la fonction value() doit être appelée à partir d'un processus de post-construction. étape, où l'objet est garanti d'être entièrement initialisé. Cela peut être fait en remplaçant la fonction value() dans la classe dérivée et en l'appelant à partir d'une méthode distincte dont l'appel est garanti après la construction. Par exemple :
struct derived : public base { virtual const int value() const { return 1; } int get_value() const { return value(); } };
Dans ce cas, la méthode get_value() peut être appelée depuis le constructeur pour obtenir la valeur correcte de "1".
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!