Le fait d'avoir au moins une méthode virtuelle dans une classe C++ (ou dans l'une de ses classes parentes) signifie que la classe aura une table virtuelle et que chaque instance aura un pointeur virtuel.
Le coût de la mémoire est donc très clair. Le plus important est le coût de la mémoire sur les instances (surtout si les instances sont petites, par exemple si elles sont juste censées contenir un entier : dans ce cas, avoir un pointeur virtuel dans chaque instance pourrait doubler la taille des instances. Quant à l'espace mémoire utilisé par les tables virtuelles, je suppose qu'il est généralement négligeable par rapport à l'espace utilisé par le code réel de la méthode.
Cela m'amène à ma question : y a-t-il un coût mesurable en termes de performances (c'est-à-dire un impact sur la vitesse) pour rendre une méthode virtuelle ? Il y aura une recherche dans la table virtuelle au moment de l'exécution, à chaque appel de méthode, donc s'il y a des appels très fréquents à cette méthode, et si cette méthode est très courte, alors il pourrait y avoir un impact mesurable sur les performances ? Je suppose que cela dépend de la plate-forme, mais quelqu'un a-t-il effectué des tests de référence ?
La raison de ma question est que je suis tombé sur un bug qui était dû au fait qu'un programmeur avait oublié de définir une méthode virtuelle. Ce n'est pas la première fois que je vois ce genre d'erreur. Et je me suis demandé pourquoi nous ajouter le mot-clé virtuel lorsque cela est nécessaire au lieu de enlever le mot-clé virtuel lorsque nous sommes absolument sûrs qu'il est no nécessaire ? Si le coût de la performance est faible, je pense que je vais simplement recommander ce qui suit dans mon équipe : il suffit de faire chaque virtuelle par défaut, y compris le destructeur, dans chaque classe, et ne la supprimez que lorsque vous en avez besoin. Cela vous semble-t-il fou ?
0 votes
Voir aussi la question de Stack Overflow : Applications IA en C++ : Quel est le coût des fonctions virtuelles ? Quelles sont les optimisations possibles ?
10 votes
Comparer des appels virtuels à des appels non virtuels n'est pas menafull. Ils offrent des fonctionnalités différentes. Si vous voulez comparer les appels de fonctions virtuelles à leur équivalent en C, vous devez ajouter le coût du code qui implémente la fonctionnalité équivalente de la fonction virtuelle.
0 votes
Ce qui est soit une déclaration d'interrupteur soit une déclaration de grand si. Si vous êtes malin, vous pouvez réimplémenter en utilisant une table de pointeurs de fonctions, mais les probabilités de vous tromper sont beaucoup plus élevées.
0 votes
Voir stackoverflow.com/questions/156257/
12 votes
La question porte sur les appels de fonction qui n'ont pas besoin d'être virtuels, la comparaison a donc un sens.
0 votes
@Mark Ransom : oui, exactement, merci. Je dis en gros "et si on définissait TOUTES les fonctions comme virtuelles, même celles qui n'ont pas vraiment besoin de l'être, et qu'on enlevait plus tard le mot clé virtuel quand on est sûr à 100% qu'il n'est pas nécessaire". En faisant cela, éviterions-nous un tas de bugs et ne perdrions-nous que des performances négligeables ?
0 votes
Si vous utilisez Visual C++, envisagez d'utiliser "override" qui est une extension non standard : msdn.microsoft.com/fr/us/library/z8ew2153.aspx . Il est très bon pour détecter ce genre de bogues au moment de la compilation.
0 votes
Duplicata possible de Pénalité de performance pour le travail avec des interfaces en C++ ?
0 votes
Rendre tout virtuel par défaut jusqu'à ce que quelqu'un justifie pourquoi cela peut/doit être non-virtuel est une politique abominable, oui.
0 votes
Related : dans ma réponse à stackoverflow.com/questions/46579750/ j'ai montré un cas où le coût du bouclage d'un vecteur de pointeurs en appelant une méthode virtuelle est peut-être 24x plus lent que le bouclage d'un vecteur de pointeurs. objets directement, où le compilateur peut auto-vectoriser après avoir mis en ligne l'appel de fonction non virtuelle . Ainsi, si vous avez le choix entre conserver plusieurs conteneurs pour différents types d'objets et conserver un tableau de pointeurs vers des objets mixtes, laisser le compilateur intégrer de petites fonctions est une très bonne chose.