Pour le virtual, je t'explique. Dans les langages objets avant C++, la notion d'objet implique celle de polymorphisme. Si B hérite de A, je peux écrire un code qui pense utiliser des A mais lui transmettre des B, tout ce passera bien, les méthodes de B seront appelées. En C++, ceci ne fonctionne que si on ajoute virtual devant les méthodes qu'on veut voir fonctionner correctement. Bien entendu, on peut toujours avoir B qui hérite de A, passer un B à un code qui attend un A et obtenir un comportement débile car les méthodes redéfinies dans B ne sont pas appelées. Cette sémantique est tout simplement pourrie. C'est d'autant plus pourri que ça dépend du mode de passage. Si A est passé par valeur, alors les méthodes de A seront toujours appelées, alors que si A est passé par référence ou pointeur, le polymorphisme fonctionne. Or, un langage doit être prévisible simplement. Un tel comportement est nuisible et ne fait que compliquer la tâche du programmeur sans aucun intérêt pratique.
Dans un langage objet qui fonctionne, toutes les méthodes sont "virtuel" par défaut. Si on a besoin d'interdire la redéfinition, on utilise un mot clé adapté, comme "final" en Java. De cette manière, on ne peut pas se tirer dans le pied en croyant avoir du polymorphisme mais en ayant en fait un truc boiteux. On peut aussi imaginer une solution à la C++ mais qui empêche de se tirer dans le pied, en ayant une seule sémantique (et pas une sémantique qui dépend du mode de passage) et en interdisant la redéfinition des méthodes non virtuel. Personnellement, j'aime moins, mais bon, c'est un choix.
Les arguments des défenseurs de la sémantique débile du C++ sont multiples et plutôt foireux.
Le plus convainquant est celui qui dit que cela facilite l'interfaçage avec du C en ayant des objets sans table des méthodes virtuelles. On peut alors passer leur contenu à des fonctions C sans soucis. On peut aussi "encapsuler" une struct C en un objet C++ en ajoutant des méthodes. Sauf qu'on sait depuis des années comment faire ça proprement : avec des objets "lights" comme dit Guillaume, c'est-à-dire des objets qui sont manipulables par valeur (contrairement aux objets de Java) et qui ne supportent pas l'héritage. Ce sont les structs du C#, mais ça existe depuis longtemps en Eiffel et Sather (et ça manque drôlement en Java).
Le plus pourri est celui qui dit que virtuel permet d'optimiser le code. C'est grotesque. De toute manière, on obtient la même chose avec du final (i.e., la possibilité de virer le passage par la table des méthodes virtuelles et d'inline les méthodes associées si ça vaut le coup). De plus, depuis Eiffel et Sather, on sait que des techniques évoluées permettent de laisser le compilateur faire ça de façon beaucoup plus efficace que le programmeur.
Voilà, voilà, tu vois, je connais un peu le sujet, mais bon, vu ton aggressivité déplacée, je suppose que tu t'en fous.
[^] # Re: C'est un troll.
Posté par boubou . En réponse à la dépêche Mono 1.0 sous le feu des projecteurs. Évalué à 2.
Pour le virtual, je t'explique. Dans les langages objets avant C++, la notion d'objet implique celle de polymorphisme. Si B hérite de A, je peux écrire un code qui pense utiliser des A mais lui transmettre des B, tout ce passera bien, les méthodes de B seront appelées. En C++, ceci ne fonctionne que si on ajoute virtual devant les méthodes qu'on veut voir fonctionner correctement. Bien entendu, on peut toujours avoir B qui hérite de A, passer un B à un code qui attend un A et obtenir un comportement débile car les méthodes redéfinies dans B ne sont pas appelées. Cette sémantique est tout simplement pourrie. C'est d'autant plus pourri que ça dépend du mode de passage. Si A est passé par valeur, alors les méthodes de A seront toujours appelées, alors que si A est passé par référence ou pointeur, le polymorphisme fonctionne. Or, un langage doit être prévisible simplement. Un tel comportement est nuisible et ne fait que compliquer la tâche du programmeur sans aucun intérêt pratique.
Dans un langage objet qui fonctionne, toutes les méthodes sont "virtuel" par défaut. Si on a besoin d'interdire la redéfinition, on utilise un mot clé adapté, comme "final" en Java. De cette manière, on ne peut pas se tirer dans le pied en croyant avoir du polymorphisme mais en ayant en fait un truc boiteux. On peut aussi imaginer une solution à la C++ mais qui empêche de se tirer dans le pied, en ayant une seule sémantique (et pas une sémantique qui dépend du mode de passage) et en interdisant la redéfinition des méthodes non virtuel. Personnellement, j'aime moins, mais bon, c'est un choix.
Les arguments des défenseurs de la sémantique débile du C++ sont multiples et plutôt foireux.
Le plus convainquant est celui qui dit que cela facilite l'interfaçage avec du C en ayant des objets sans table des méthodes virtuelles. On peut alors passer leur contenu à des fonctions C sans soucis. On peut aussi "encapsuler" une struct C en un objet C++ en ajoutant des méthodes. Sauf qu'on sait depuis des années comment faire ça proprement : avec des objets "lights" comme dit Guillaume, c'est-à-dire des objets qui sont manipulables par valeur (contrairement aux objets de Java) et qui ne supportent pas l'héritage. Ce sont les structs du C#, mais ça existe depuis longtemps en Eiffel et Sather (et ça manque drôlement en Java).
Le plus pourri est celui qui dit que virtuel permet d'optimiser le code. C'est grotesque. De toute manière, on obtient la même chose avec du final (i.e., la possibilité de virer le passage par la table des méthodes virtuelles et d'inline les méthodes associées si ça vaut le coup). De plus, depuis Eiffel et Sather, on sait que des techniques évoluées permettent de laisser le compilateur faire ça de façon beaucoup plus efficace que le programmeur.
Voilà, voilà, tu vois, je connais un peu le sujet, mais bon, vu ton aggressivité déplacée, je suppose que tu t'en fous.