Quand marquer une fonction en C ++ en tant que virtuelle?

En raison de la nature C ++ de la liaison statique pour les méthodes, cela affecte les appels polymorphes.

De Wikipedia:

Bien que les frais généraux impliqués dans ce mécanisme de répartition soient faibles, ils peuvent néanmoins être importants pour certaines applications que le langage a été conçu pour cibler. Pour cette raison, Bjarne Stroustrup, le concepteur de C ++, a choisi de rendre la répartition dynamic facultative et non par défaut. Seules les fonctions déclarées avec le mot-clé virtual seront dissortingbuées en fonction du type d’exécution de l’object. d’autres fonctions seront dissortingbuées en fonction du type statique de l’object.

Donc le code:

Polygon* p = new Triangle; p->area(); 

à condition que area() soit une fonction non-virtual de la classe Parent qui est overridden par la classe Child, le code ci-dessus appelle la Parent's class method laquelle le développeur peut ne pas s’attendre. (grâce à la liaison statique que j’ai introduite)

Donc, si je veux écrire une classe qui sera utilisée par d’autres (par exemple, une bibliothèque), devrais-je rendre toutes mes fonctions virtuelles, pour que le code précédent puisse fonctionner comme prévu?

La réponse est simple: si vous souhaitez que les fonctions de votre classe soient remplacées par le polymorphism d’exécution, vous devez les marquer comme virtual et non si vous ne le souhaitez pas.

Ne marquez pas vos fonctions comme virtual simplement parce que vous estimez qu’elles confèrent une flexibilité supplémentaire, pensez plutôt à votre conception et au but de l’exposition d’une interface. Par exemple: si votre classe n’est pas conçue pour être héritée, rendre vos fonctions de membre virtuelles sera trompeur. Les conteneurs de la bibliothèque standard, qui ne sont pas censés être hérités et ne possèdent donc pas de destructeurs virtuels, en sont un bon exemple.

Il n’y a pas de raison de ne pas marquer toutes vos fonctions membres comme virtuelles, de citer des pénalités de performance, un type de classe autre que POD, etc., mais si vous voulez vraiment que votre classe soit destinée à une surexécution, alors c’est le but de celui-ci et de son sujet et sur les soi-disant lacunes.

Marquez-le comme étant virtuel si les classes dérivées doivent pouvoir remplacer cette méthode. C’est aussi simple que ça.

En règle générale, vous ne devez marquer une fonction virtuelle que si la classe est explicitement conçue pour être utilisée comme classe de base et que cette fonction est conçue pour être remplacée. En pratique, la plupart des fonctions virtuelles seront virtuelles dans la classe de base. Et sauf en cas d’inversion d’appel, où vous ne fournissez pas explicitement de contrat pour la fonction dominante, les fonctions virtuelles doivent être privées (ou au mieux protégées), et encapsulées avec des fonctions non virtuelles appliquant le contrat.

En termes de performances de la mémoire, vous obtenez une table de pointeurs virtuels si quelque chose est virtuel. Une façon de le regarder est donc “s’il vous plaît un, s’il vous plaît à tous”. Sinon, comme les autres le disent, marquez-les comme virtuels si vous voulez qu’ils soient remplaçables de telle sorte que l’appel de cette méthode sur une classe de base signifie que les versions spécialisées sont exécutées.

C’est fondamentalement l’idée. En fait, si vous utilisez une classe parente, je ne pense pas que vous deviez remplacer toutes les méthodes, il suffit donc de les rendre virtual si vous pensez les utiliser de cette façon.