Junior
Que savez-vous du mot-clé virtual en C++?
sobes.tech IA
Réponse de l'IA
virtual en C++ est utilisé pour déclarer des fonctions virtuelles dans la classe de base. Cela permet d'implémenter le polymorphisme à l'exécution (polymorphisme en temps d'exécution).
Application :
- Définit une fonction dans la classe de base qui peut être redéfinie (override) dans les classes dérivées.
- Lorsqu'une fonction virtuelle est appelée via un pointeur ou une référence à la classe de base, c'est en réalité l'implémentation de la fonction dans l'objet de la classe dérivée qui est appelée (si elle a été redéfinie). Cela se produit à l'exécution via la table des fonctions virtuelles (vtable).
Points clés :
- Seules les fonctions membres de classe peuvent être virtuelles. Les fonctions globales, membres statiques et constructeurs ne peuvent pas être virtuels.
- Les destructeurs peuvent et doivent souvent être virtuels pour éviter les fuites de mémoire lors de la suppression d'objets de classes dérivées via un pointeur vers la classe de base.
- Si une fonction est déclarée
virtualdans la classe de base, elle reste automatiquement virtuelle dans toutes les classes dérivées, même si le mot-clévirtualn'est pas utilisé explicitement (bien qu'il soit recommandé d'utiliservirtualetoverridedans les classes dérivées pour plus de clarté). - Les fonctions virtuelles pures sont déclarées avec
= 0et rendent la classe abstraite. Une telle classe ne peut pas être instanciée directement.
Exemple :
#include <iostream>
class Base {
public:
virtual void print() {
std::cout << "De Base" << std::endl;
}
virtual ~Base() {
std::cout << "Destructeur de Base" << std::endl;
}
};
class Derived : public Base {
public:
void print() override { // Utilisation de override pour indiquer la redéfinition
std::cout << "De Derived" << std::endl;
}
~Derived() override { // Utilisation de override
std::cout << "Destructeur de Derived" << std::endl;
}
};
int main() {
Base* ptr = new Derived(); // Pointeur vers la classe de base pointant vers un objet dérivé
ptr->print(); // Appelle Derived::print() grâce à la fonction virtuelle
delete ptr; // Appelle les destructeurs de Derived puis de Base grâce au destructeur virtuel
return 0;
}
Concepts liés :
- vtable (table des fonctions virtuelles) : Table de pointeurs vers les fonctions virtuelles de la classe. Chaque objet avec des fonctions virtuelles contient un pointeur invisible (vptr) vers la vtable de sa classe.
- vptr (pointeur vers vtable) : Nécessaire pour déterminer la fonction à appeler en temps d'exécution.
= 0(fonction virtuelle pure) : Indique que la fonction n'a pas d'implémentation dans cette classe, rendant la classe abstraite.override(spécificateur de redéfinition) : Indique explicitement que la fonction dans la classe dérivée redéfinit une fonction virtuelle de la classe de base. Aide le compilateur à détecter les erreurs si la signature ne correspond pas.final(spécificateur) : Interdit toute redéfinition ultérieure de la fonction virtuelle ou héritage de la classe.
En résumé : virtual est le mécanisme principal pour réaliser le polymorphisme via l'héritage et le liaison dynamique en C++.