Pourquoi ne pas toujours declarer les classes virtuels

Pourquoi ne pas toujours declarer les classes virtuels - C++ - Programmation

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

Reply

Marsh Posté le 20-08-2006 à 15:06:52   

Reply

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 ...

Reply

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.

Reply

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 :
  1. class BaseClass
  2. {
  3. public:
  4. virtual void DoStuff();
  5. };


Laquelle de ces deux écritures de la méthode DoStuff est à privilégier ?

Code :
  1. class DerivedClass
  2. {
  3. public:
  4. virtual void DoStuff();
  5. };


ou

Code :
  1. class DerivedClass
  2. {
  3. public:
  4. void DoStuff();
  5. };

Reply

Marsh Posté le 20-08-2006 à 20:08:53    

celle ci:

Code :
  1. class BaseClass
  2. {
  3.    virtual void DoStuff() = 0;
  4. };
  5. class DerivedClass: public BaseClass
  6. {
  7.    public:
  8.       DerivedClass();
  9.       void DoStuff();
  10. };


Message édité par _darkalt3_ le 20-08-2006 à 20:13:30

---------------
Töp of the plöp
Reply

Marsh Posté le 20-08-2006 à 22:26:57    

Mon prof de génei log disait : "virtual un jour, virtual toujours :o"
 

Code :
  1. class BaseClass
  2. {
  3.    virtual void DoStuff() = 0;
  4. };
  5. class DerivedClass: public BaseClass
  6. {
  7.    public:
  8.       DerivedClass();
  9.       virtual void DoStuff();
  10. };


 
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.

Reply

Marsh Posté le 20-08-2006 à 22:33:47    

Joel F a écrit :

Mon prof de génei log disait : "virtual un jour, virtual toujours :o"


Reply

Marsh Posté le 20-08-2006 à 23:30:18    

j'en prends bonne note :o


---------------
Töp of the plöp
Reply

Marsh 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

Reply

Marsh Posté le 21-08-2006 à 03:18:40    

Tu peux clarifier un peux ton exemple ? L'erreur viendrait d'où ?

Reply

Marsh Posté le 21-08-2006 à 03:18:40   

Reply

Marsh Posté le 21-08-2006 à 10:48:18    

nan mais là tu parles d'héritage virtuel :o

Reply

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 ?

Reply

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.


---------------
Il y a autant d'atomes d'oxygène dans une molécule d'eau que d'étoiles dans le système solaire.
Reply

Marsh Posté le 21-08-2006 à 17:51:52    


 
J'ai bien dit classes.

Reply

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.


Message édité par tfpsly le 21-08-2006 à 18:43:57
Reply

Marsh Posté le 21-08-2006 à 18:57:43    

Ok merci

Reply

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 ?

Message cité 1 fois
Message édité par slash33 le 27-08-2006 à 00:20:32
Reply

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.

Message cité 1 fois
Message édité par tfpsly le 27-08-2006 à 09:49:41
Reply

Marsh Posté le 27-08-2006 à 11:23:52    

l'heritage aussi peut etre specifié virtuel

Reply

Marsh Posté le 27-08-2006 à 20:23:48    

skelter a écrit :

l'heritage aussi peut etre specifié virtuel


Détaille STP. Ca m'intéresse. :)

Reply

Marsh 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)


---------------
Stick a parrot in a Call of Duty lobby, and you're gonna get a racist parrot. — Cody
Reply

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.

Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed