Pourquoi ne pas toujours declarer les classes virtuels - C++ - Programmation
Marsh Posté le 20-08-2006 à 15:28:37
c'est exactement ça "pour ne pas perdre de temps" ... Pour l'implémentation du mot clé "virtual", le compilateur va utiliser une "virtual method table".
A chaque fois que tu appeleras ta methode dans ton code, il va déjà récupérer le pointeur de fonction de ta methode pour savoir quelle fonction appelée, ainsi si tu as un code critique appellé plusieur fois, tu vas perdre une paire de cycle (tu vas perdre un peu de temps), c'est sur que ça ne sera pas visible si ta fonction est appellé 1000 fois durant l'execution ...
Ensuite il y a le problème de clareté du code, si tu travailles sur un petit projet ça ira, mais si tu as un projet plus complexe, le mot virtual n'aura plus de signification puisque tu l'appelleras à chaque fois ...
Marsh Posté le 20-08-2006 à 18:41:50
Parce que la philosophie du C++, c'est ne payer que pour ce qu'on utilise. D'autres langages comme C# ont le même comportement par défaut -- non virtuel --.
Et puis pour pas mal de type genre POD ou template, virtual rajouterait un surcout non négligeable dans pas mal de cas.
La seule conduite c'est : mets virtual quand tu en as besoin. Ne te préoccupes pas des performance, fais un programme correct et élégant.
Marsh Posté le 20-08-2006 à 19:41:47
Puisqu'on parle de virtual...
Partant d'une classe de base héritée par une autre :
Code :
|
Laquelle de ces deux écritures de la méthode DoStuff est à privilégier ?
Code :
|
ou
Code :
|
Marsh Posté le 20-08-2006 à 20:08:53
celle ci:
Code :
|
Marsh Posté le 20-08-2006 à 22:26:57
Mon prof de génei log disait : "virtual un jour, virtual toujours "
Code :
|
ca ne chaneg rien au perfs ni à la sémantique mais ca permet d'un coup d'oeil de reperer les éléments hérités de BaseClass. ca peut etre utile si DerivedClass est potentiellement dérivable par la suite.
Marsh Posté le 20-08-2006 à 22:33:47
ReplyMarsh Posté le 21-08-2006 à 00:30:46
Ok, mais quand on créé une bibliotheque, si un jour j'ai une classe qui herite de 2 classe qui herite d'une seul autre classe et que je n'ai pas mit virtual a cette classe, ca va générer une erreur.
Merci
Marsh Posté le 21-08-2006 à 03:18:40
Tu peux clarifier un peux ton exemple ? L'erreur viendrait d'où ?
Marsh Posté le 21-08-2006 à 13:01:01
Si une classe B et C herite de A et que D herite de B et C, dc C herite aussi de A (dans mon cas pas forcement), si D veut utiliser une focntion de A il ne sait pas si il doit prendre le A de B ou de C. C'est a sa que sert le mot virtual, non ?
Marsh Posté le 21-08-2006 à 16:15:13
Les méthodes virtuelles n'ont strictement rien à voir avec les classes virtuelles, le même mot sert pour 2 choses bien distinctes.
Marsh Posté le 21-08-2006 à 18:24:08
Erreur de compilation ? Non. Il ne peut y avoir de problème que si ta deuxième et troisième classe ont une méthode avec le même prototype et que ta dernière classe ne la redéfinit pas, car cette méthode sera alors ambigue.
Erreur de logique ? Ca dépend de ton programme et de ce que tu veux faire. Si tu le fais correctement, non.
Si une classe donnée a des méthodes virtuelles, alors
1) Ton programme créé pour ce type de classe un tableau contenant les adresses mémoires des méthodes virtuelles en question (et/ou des méthodes virtuelles héritées si elles n'ont pas été redéfinies). C'est ce que l'on appelle la TMV (Table des Méthodes Virtuelles) ou VMT en Anglais.
2) chaque instance de cette classe possède un pointeur sur cette TMV. Lorsque tu appelles une méthode donnée sur une instance, ton programme va en fait accéder à la TMV, y lire l'adresse de la méthode à appeler et l'exécuter.
Exemple :
Classe A avec méthode virtuelle v.
Classe B héritant de A et redéfinissant v
Classe C héritant de A et redéfinissant v
Classe D héritant de B et C et redéfinissant v
A* a1 = new A;
A* a2 = new B;
A* a3 = new C;
A* a4 = new D; // Il faudra probablement caster en C* ou B* auparavant.
a1->v(); // Appelle A::v
a2->v(); // Appelle B::v
a3->v(); // Appelle C::v
a4->v(); // Appelle D::v
Alors que si v n'était pas virtuelle, les 4 appels auraient exécuter A::v.
Marsh Posté le 27-08-2006 à 00:19:56
Heu c'est quoi une classe virtuelle ??? Vous parlez de classes polymorphiques, abstraction, interface ou non ?
Marsh Posté le 27-08-2006 à 09:48:01
slash33 a écrit : Heu c'est quoi une classe virtuelle ??? |
Un abus de langage, ça n'existe pas en C++. Seules les méthodes peuvent être virtuelles.
Marsh Posté le 27-08-2006 à 11:23:52
ReplyMarsh Posté le 27-08-2006 à 20:23:48
ReplyMarsh Posté le 27-08-2006 à 20:59:57
tfpsly a écrit : Un abus de langage, ça n'existe pas en C++. Seules les méthodes peuvent être virtuelles. |
Pas spécialement, on peut considérer qu'une classe est virtuelle si toutes ses méthodes sont virtuelles.
Elle se comporte alors comme une interface (d'ailleurs les interfaces java sont implémentées avec des classes virtuelles pures)
Marsh Posté le 27-08-2006 à 23:26:06
Une interface se définit habituellement par une classe abstraite (qui contient donc des méthodes virtuelles pures) pour être plus exact
Une classe ne contenant que des méthodes virtuelles mais définies n'est en général pas une bonne méthode de faire une interface.
Marsh Posté le 20-08-2006 à 15:06:52
Bonjour,
je me demandais pourquoi on ne declarai pas toujours des classes virtuels pour eviter les problemes avec l'heritage, il y a t il un avantage a ne pas le faire ou est ce juste pour ne pas perdre de temps?
Merci