2010-06-18 6 views
2

J'étais curieux au sujet du C++ et de l'héritage virtuel - en particulier, la façon dont les conflits vtable sont résolus entre les classes basse et enfant. Je ne vais pas prétendre comprendre les détails sur la façon dont ils fonctionnent, mais ce que j'ai lu jusqu'à présent, c'est qu'ils sont un petit retard causé par l'utilisation de fonctions virtuelles en raison de cette résolution. Ma question est alors si la classe de base est vide - à savoir, ses fonctions virtuelles sont définies comme:Résolution de vtable C++ avec héritage virtuel

virtual void doStuff() = 0; 

Est-ce que cela signifie que la résolution n'est pas nécessaire, car il n'y a qu'un seul ensemble de fonctions à choisir? Pardonnez-moi si c'est une question stupide - comme je l'ai dit, je ne comprends pas comment fonctionne vtables donc je ne sais pas vraiment mieux.

EDIT

Donc, si j'ai une classe abstraite avec deux classes d'enfants séparés:

A 
/\ 
/ \ 
B  C 

Il n'y a pas frappé les performances lors de l'appel des fonctions des classes d'enfants par rapport à dire, un seul héritage libre classe?

+2

Cochez ici une de mes questions précédentes: http://stackoverflow.com/questions/99297/at-as-deep-of-a-level-as-possible-comment-voir-les-fonctions-virtuelles-implement –

Répondre

5

Il n'y a pas de hit pour appeler nonvirtual fonctions dans la classe enfant. Si vous appelez une version surchargée de votre fonction virtuelle pure comme dans votre exemple, alors la pénalité virtuelle peut toujours exister. En général, il est difficile pour les compilateurs d'optimiser l'utilisation de la table virtuelle sauf dans des circonstances très spécifiques, où elle connaît le type exact de valeur de l'objet en question (à partir du contexte).

Mais ne vous inquiétez pas sérieusement de la surcharge. Il sera si peu que dans la pratique, vous ne rencontrerez presque certainement jamais une situation où c'est la partie du code qui engendre des goulots d'étranglement au niveau des performances. Utilisez des fonctions virtuelles là où elles ont du sens pour votre conception et ne vous inquiétez pas de la (minuscule) pénalité de performance.

+0

Merci pour la réponse claire et les conseils généraux sur le codage =) – Tomas

+2

J'ai expérimentalement mesuré le surdébit d'un appel de fonction virtuelle comme étant supérieur d'environ 7 nanosecondes à un appel de fonction directe (sur un processeur 3GHz). Que cela soit important ou non dépend de ce que vous faites. – Crashworks

+1

@Crashworks: Il n'y a aucun moyen de "mesurer" la surcharge de la fonction virtuelle, car cela dépend vraiment de la situation, ce que vous avez mesuré est un cas très spécifique –

0

La frappe 'double dispatch' ne se produit que lorsque la méthode est virtuelle. Si la méthode dérivée n'est pas virtuelle, il n'y a aucun impact sur les performances.

+0

Mais si la méthode parente est purement virtuelle comme dans l'exemple de l'OP, la méthode dérivée est également virtuelle. –

+0

Correct. Merci. –

2

Je ne sais pas de quoi «un ensemble de fonctions» vous parlez. Vous avez deux classes dérivées - B et C - avec chacune ayant son propre ensemble de fonctions virtuelles. Ainsi, vous avez au moins deux ensembles, même si toutes les fonctions dans A sont pures. L'envoi virtuel se produit lorsque le compilateur ne connaît pas le type dynamique de l'objet avec lequel il travaille.

Par exemple, si vous avez un pointeur A *p, il peut pointer vers un objet de type B ou de type C. Si le compilateur ne sait pas quel est le type réel de l'objet pointé par p, il devra utiliser la répartition virtuelle pour appeler les fonctions virtuelles via p.

P.S. Il n'y a pas d '"héritage virtuel" dans votre exemple. Le terme héritage virtuel en C++ a sa propre signification. Et vous ne parlez pas d'héritage virtuel ici.

+0

Quand j'ai dit un ensemble de fonctions, je voulais dire les fonctions d'une seule classe. Désolé pour la chose de l'héritage virtuel. Si je pouvais poser une autre question, quel est le coût de la distribution vtable? Commencerait à prendre un tole quand vous l'utilisez très souvent? Je pense à avoir plusieurs versions de la plupart des objets dans mon projet, donc l'utilisateur peut à la demande recharger le programme avec des objets de débogage qui font des vérifications supplémentaires, la journalisation et ect. – Tomas