
Envoyé par
moi même
Une école tend à définir toutes les fonctions en virtuel : « mettons la fonction en virtuel, quelqu'un pourrait vouloir la supplanter ». Seulement...
Si une fonction ne correspond pas à un point de variation [Coplien1998] prévu lors de la conception, il reste peu probable que l'on puisse étendre le système simplement parce que la fonction était virtuelle. Bien souvent, rajouter correctement un point de variation non initialement prévu demande un refactoring non trivial du code, c'est à dire bien plus qu'ajouter un simple "virtual".
Bien sûr, plus les fonctions d'une classe respectent le principe, « Une fonction doit faire une chose, et doit le faire bien » (aka les fonctions doivent être courtes, avec peu de niveaux d'imbrications, ...), plus il est simple d'introduire des points de variations à la volée. Seulement si toutes sont virtuelles, cela veut aussi dire que toutes ces fonctions membre (en nombre plus ou moins important) peuvent être supplantées. Les classes filles auraient alors une visibilité complète de la classe mère. De cette rupture d'encapsulation inter-générations, il devient alors vite complexe de savoir ce qui peut être supplanté, et sous quelles conditions (contraintes).
De plus, les hiérarchies polymorphes ayant naturellement une sémantique d'entité, définir virtuelle une quelconque fonction membre d'une classe à sémantique de valeur n'a aucun sens. C'est aussi pour cela qu'aucun conteneur de la bibliothèque standard ne dispose de fonction membre virtuelle.
Enfin, virtual introduit un sur-coût lors d'un appel de fonction où il n'était pas nécessaire. De fait, pour des raisons d'optimisation, on évite également de payer inutilement pour un service dont on n'a pas besoin : à savoir un branchement conditionnel déterminé à l'exécution (NB: il n'y aucune différence de rapidité, voire de meilleures performances sont à attendre de virtual par rapport à des if en chaîne, un switch-case, des tables d'indirection, etc.).
Partager