je souscris à l'intégralité de ton point.
en fait, ma surprise venait de là: déconseiller une approche pour l ui
préférer quelque chose ne pouvant répondre aux mêmes exigences est
surprenant.
Le polymorphisme peut être utilisé dans presque tous les cas à la p lace
des templates.
On n'y perd alors en performance et en type safety.
C'est pour ça que si on peut utiliser les templates à la place, c'est
conseillé.
je souscris à l'intégralité de ton point.
en fait, ma surprise venait de là: déconseiller une approche pour l ui
préférer quelque chose ne pouvant répondre aux mêmes exigences est
surprenant.
Le polymorphisme peut être utilisé dans presque tous les cas à la p lace
des templates.
On n'y perd alors en performance et en type safety.
C'est pour ça que si on peut utiliser les templates à la place, c'est
conseillé.
je souscris à l'intégralité de ton point.
en fait, ma surprise venait de là: déconseiller une approche pour l ui
préférer quelque chose ne pouvant répondre aux mêmes exigences est
surprenant.
Le polymorphisme peut être utilisé dans presque tous les cas à la p lace
des templates.
On n'y perd alors en performance et en type safety.
C'est pour ça que si on peut utiliser les templates à la place, c'est
conseillé.
Ah, bien ? Et comment est-ce qu'on utilise le polymorphisme
dynamique pour enforcer des invariants sur le typage, lors de la
compilation ?
On peut parfois perdre un peu en performance. C'est rarement
signifiant, mais si le profiler dit que c'est un problème, il
faut y agir. Autrement, ça tombe sur la qualification de
l'optimisation prématurée.
Et je n'ai jamais vue de problème de type safety avec le
polymorphisme dynamique.
Non. Ce qui est conseillé, c'est d'utiliser la technique qui
convient. Et dans les rares cas où les deux conviennent, de
préférer le polymorphisme dynamique, à cause de la souplesse
supplémentaire.
(Ce qui est aussi conseillé, c'est de ne se servir ni de l'un ni
de l'autre sans que ça apporte quelque chose de réel et de
concret. La généricité prématurée est aussi mauvaise que
l'optimisation prématurée, et le code le plus simple qui remplit
le contrat est toujours le meilleur.)
Ah, bien ? Et comment est-ce qu'on utilise le polymorphisme
dynamique pour enforcer des invariants sur le typage, lors de la
compilation ?
On peut parfois perdre un peu en performance. C'est rarement
signifiant, mais si le profiler dit que c'est un problème, il
faut y agir. Autrement, ça tombe sur la qualification de
l'optimisation prématurée.
Et je n'ai jamais vue de problème de type safety avec le
polymorphisme dynamique.
Non. Ce qui est conseillé, c'est d'utiliser la technique qui
convient. Et dans les rares cas où les deux conviennent, de
préférer le polymorphisme dynamique, à cause de la souplesse
supplémentaire.
(Ce qui est aussi conseillé, c'est de ne se servir ni de l'un ni
de l'autre sans que ça apporte quelque chose de réel et de
concret. La généricité prématurée est aussi mauvaise que
l'optimisation prématurée, et le code le plus simple qui remplit
le contrat est toujours le meilleur.)
Ah, bien ? Et comment est-ce qu'on utilise le polymorphisme
dynamique pour enforcer des invariants sur le typage, lors de la
compilation ?
On peut parfois perdre un peu en performance. C'est rarement
signifiant, mais si le profiler dit que c'est un problème, il
faut y agir. Autrement, ça tombe sur la qualification de
l'optimisation prématurée.
Et je n'ai jamais vue de problème de type safety avec le
polymorphisme dynamique.
Non. Ce qui est conseillé, c'est d'utiliser la technique qui
convient. Et dans les rares cas où les deux conviennent, de
préférer le polymorphisme dynamique, à cause de la souplesse
supplémentaire.
(Ce qui est aussi conseillé, c'est de ne se servir ni de l'un ni
de l'autre sans que ça apporte quelque chose de réel et de
concret. La généricité prématurée est aussi mauvaise que
l'optimisation prématurée, et le code le plus simple qui remplit
le contrat est toujours le meilleur.)
Et comme je l'ai déjà dit, quasiment tout ce qu'on peut implémenter avec
les templates peut s'implémenter avec le polymorphisme.
Comment ils feraient sinon les langages objet sans templates pour faire
des choses similaires ? En Java par exemple, les conteneurs sont en fait
des conteneurs de Object, ce qui oblige d'ailleurs à caster quand on
veut utiliser l'objet.
Et comme je l'ai déjà dit, quasiment tout ce qu'on peut implémenter avec
les templates peut s'implémenter avec le polymorphisme.
Comment ils feraient sinon les langages objet sans templates pour faire
des choses similaires ? En Java par exemple, les conteneurs sont en fait
des conteneurs de Object, ce qui oblige d'ailleurs à caster quand on
veut utiliser l'objet.
Et comme je l'ai déjà dit, quasiment tout ce qu'on peut implémenter avec
les templates peut s'implémenter avec le polymorphisme.
Comment ils feraient sinon les langages objet sans templates pour faire
des choses similaires ? En Java par exemple, les conteneurs sont en fait
des conteneurs de Object, ce qui oblige d'ailleurs à caster quand on
veut utiliser l'objet.
Ah, bien ? Et comment est-ce qu'on utilise le polymorphisme
dynamique pour enforcer des invariants sur le typage, lors de la
compilation ?
On ne peut pas, puisqu'on perd en type safety comme je l'ai dit.
On peut parfois perdre un peu en performance. C'est rarement
signifiant, mais si le profiler dit que c'est un problème, il
faut y agir. Autrement, ça tombe sur la qualification de
l'optimisation prématurée.
Cela n'est pas nécessairement de l'optimisation prématurée.
Parfois il faut savoir concevoir directement dès le début de manièr e la
plus flexible tout en étant le plus performant, car on sait que le
composant est un composant bas-niveau qui sera fort utilisé par le
programme.
Et je n'ai jamais vue de problème de type safety avec le
polymorphisme dynamique.
C'est pourtant tout le principe du truc, puisqu'on passe par un type
abstrait qui peut alors englober toutes les possibilités des types
fournis via dérivation.
On remplace
template<typename T>
void ma_fonction(T& t);
par
void ma_fonction(Object& t);
Et on fait dériver tous les types utilisables avec ma_fonction de Objec t.
C'est plus ou moins comme ceci que fonctionnent tous les langages
"objet" qui dérivent tous leurs types d'un type abstrait unique.
Bien entendu en C++, l'idéal est de pouvoir réduire l'utilisation de
l'objet à des fonctions particulières qu'on pourra rendre virtuelles.
Pour un vrai exemple, on peut prendre les foncteurs.
template<typename F>
void apply_functor(F &f);
Qu'on peut remplacer par
void apply_functor(function<signature du foncteur>& f);
(en fait l'exemple n'est pas parfait puisqu'ici on perd la possibilité
d'overloading à cause de la signature fixée -- mais bon j'ai pas
d'autres idées où les deux solutions sont vraiment utiles)
Non. Ce qui est conseillé, c'est d'utiliser la technique qui
convient. Et dans les rares cas où les deux conviennent, de
préférer le polymorphisme dynamique, à cause de la souplesse
supplémentaire.
Conseillé par qui ?
Les conseils que j'ai donné sont ceux donnés non seulement par des
membres du comité mais aussi par de grandes entreprises ou fournisseurs
de compilateurs.
Et comme je l'ai déjà dit, quasiment tout ce qu'on peut
implémenter avec les templates peut s'implémenter avec le
polymorphisme.
Comment ils feraient sinon les langages objet sans templates pour faire
des choses similaires ? En Java par exemple, les conteneurs sont en fait
des conteneurs de Object, ce qui oblige d'ailleurs à caster quand on
veut utiliser l'objet.
(Ce qui est aussi conseillé, c'est de ne se servir ni de l'un ni
de l'autre sans que ça apporte quelque chose de réel et de
concret. La généricité prématurée est aussi mauvaise que
l'optimisation prématurée, et le code le plus simple qui remplit
le contrat est toujours le meilleur.)
Pourtant l'un des buts de la programmation c'est quand même la
réutilisabilité des composants.
Et pour qu'un composant soit réutilisable, il faut qu'il soit
suffisamment flexible et générique.
Ah, bien ? Et comment est-ce qu'on utilise le polymorphisme
dynamique pour enforcer des invariants sur le typage, lors de la
compilation ?
On ne peut pas, puisqu'on perd en type safety comme je l'ai dit.
On peut parfois perdre un peu en performance. C'est rarement
signifiant, mais si le profiler dit que c'est un problème, il
faut y agir. Autrement, ça tombe sur la qualification de
l'optimisation prématurée.
Cela n'est pas nécessairement de l'optimisation prématurée.
Parfois il faut savoir concevoir directement dès le début de manièr e la
plus flexible tout en étant le plus performant, car on sait que le
composant est un composant bas-niveau qui sera fort utilisé par le
programme.
Et je n'ai jamais vue de problème de type safety avec le
polymorphisme dynamique.
C'est pourtant tout le principe du truc, puisqu'on passe par un type
abstrait qui peut alors englober toutes les possibilités des types
fournis via dérivation.
On remplace
template<typename T>
void ma_fonction(T& t);
par
void ma_fonction(Object& t);
Et on fait dériver tous les types utilisables avec ma_fonction de Objec t.
C'est plus ou moins comme ceci que fonctionnent tous les langages
"objet" qui dérivent tous leurs types d'un type abstrait unique.
Bien entendu en C++, l'idéal est de pouvoir réduire l'utilisation de
l'objet à des fonctions particulières qu'on pourra rendre virtuelles.
Pour un vrai exemple, on peut prendre les foncteurs.
template<typename F>
void apply_functor(F &f);
Qu'on peut remplacer par
void apply_functor(function<signature du foncteur>& f);
(en fait l'exemple n'est pas parfait puisqu'ici on perd la possibilité
d'overloading à cause de la signature fixée -- mais bon j'ai pas
d'autres idées où les deux solutions sont vraiment utiles)
Non. Ce qui est conseillé, c'est d'utiliser la technique qui
convient. Et dans les rares cas où les deux conviennent, de
préférer le polymorphisme dynamique, à cause de la souplesse
supplémentaire.
Conseillé par qui ?
Les conseils que j'ai donné sont ceux donnés non seulement par des
membres du comité mais aussi par de grandes entreprises ou fournisseurs
de compilateurs.
Et comme je l'ai déjà dit, quasiment tout ce qu'on peut
implémenter avec les templates peut s'implémenter avec le
polymorphisme.
Comment ils feraient sinon les langages objet sans templates pour faire
des choses similaires ? En Java par exemple, les conteneurs sont en fait
des conteneurs de Object, ce qui oblige d'ailleurs à caster quand on
veut utiliser l'objet.
(Ce qui est aussi conseillé, c'est de ne se servir ni de l'un ni
de l'autre sans que ça apporte quelque chose de réel et de
concret. La généricité prématurée est aussi mauvaise que
l'optimisation prématurée, et le code le plus simple qui remplit
le contrat est toujours le meilleur.)
Pourtant l'un des buts de la programmation c'est quand même la
réutilisabilité des composants.
Et pour qu'un composant soit réutilisable, il faut qu'il soit
suffisamment flexible et générique.
Ah, bien ? Et comment est-ce qu'on utilise le polymorphisme
dynamique pour enforcer des invariants sur le typage, lors de la
compilation ?
On ne peut pas, puisqu'on perd en type safety comme je l'ai dit.
On peut parfois perdre un peu en performance. C'est rarement
signifiant, mais si le profiler dit que c'est un problème, il
faut y agir. Autrement, ça tombe sur la qualification de
l'optimisation prématurée.
Cela n'est pas nécessairement de l'optimisation prématurée.
Parfois il faut savoir concevoir directement dès le début de manièr e la
plus flexible tout en étant le plus performant, car on sait que le
composant est un composant bas-niveau qui sera fort utilisé par le
programme.
Et je n'ai jamais vue de problème de type safety avec le
polymorphisme dynamique.
C'est pourtant tout le principe du truc, puisqu'on passe par un type
abstrait qui peut alors englober toutes les possibilités des types
fournis via dérivation.
On remplace
template<typename T>
void ma_fonction(T& t);
par
void ma_fonction(Object& t);
Et on fait dériver tous les types utilisables avec ma_fonction de Objec t.
C'est plus ou moins comme ceci que fonctionnent tous les langages
"objet" qui dérivent tous leurs types d'un type abstrait unique.
Bien entendu en C++, l'idéal est de pouvoir réduire l'utilisation de
l'objet à des fonctions particulières qu'on pourra rendre virtuelles.
Pour un vrai exemple, on peut prendre les foncteurs.
template<typename F>
void apply_functor(F &f);
Qu'on peut remplacer par
void apply_functor(function<signature du foncteur>& f);
(en fait l'exemple n'est pas parfait puisqu'ici on perd la possibilité
d'overloading à cause de la signature fixée -- mais bon j'ai pas
d'autres idées où les deux solutions sont vraiment utiles)
Non. Ce qui est conseillé, c'est d'utiliser la technique qui
convient. Et dans les rares cas où les deux conviennent, de
préférer le polymorphisme dynamique, à cause de la souplesse
supplémentaire.
Conseillé par qui ?
Les conseils que j'ai donné sont ceux donnés non seulement par des
membres du comité mais aussi par de grandes entreprises ou fournisseurs
de compilateurs.
Et comme je l'ai déjà dit, quasiment tout ce qu'on peut
implémenter avec les templates peut s'implémenter avec le
polymorphisme.
Comment ils feraient sinon les langages objet sans templates pour faire
des choses similaires ? En Java par exemple, les conteneurs sont en fait
des conteneurs de Object, ce qui oblige d'ailleurs à caster quand on
veut utiliser l'objet.
(Ce qui est aussi conseillé, c'est de ne se servir ni de l'un ni
de l'autre sans que ça apporte quelque chose de réel et de
concret. La généricité prématurée est aussi mauvaise que
l'optimisation prématurée, et le code le plus simple qui remplit
le contrat est toujours le meilleur.)
Pourtant l'un des buts de la programmation c'est quand même la
réutilisabilité des composants.
Et pour qu'un composant soit réutilisable, il faut qu'il soit
suffisamment flexible et générique.
Et comme je l'ai déjà dit, quasiment tout ce qu'on peut implément er avec
les templates peut s'implémenter avec le polymorphisme.
Comment ils feraient sinon les langages objet sans templates pour faire
des choses similaires ? En Java par exemple, les conteneurs sont en fait
des conteneurs de Object, ce qui oblige d'ailleurs à caster quand on
veut utiliser l'objet.
Je pense que l'on n'est pas d'accord sur le terme "implémentable". Pour
moi, un conteneur typé n'est pas implémentable en Java (sauf
introduction des génériques), alors que pour toi, il est implémenta ble,
mais il faut caster. Le fait de devoir caster (et le fait aussi que le
contenu doive dériver d'une classe de base) n'est pas pour moi un dét ail
annexe, mais un aspect fondamental.
Donc, pour moi, dans ce cas, le polymorphisme dynamique ne
résoud pas le problème. Les templates le résolvent.
Et comme je l'ai déjà dit, quasiment tout ce qu'on peut implément er avec
les templates peut s'implémenter avec le polymorphisme.
Comment ils feraient sinon les langages objet sans templates pour faire
des choses similaires ? En Java par exemple, les conteneurs sont en fait
des conteneurs de Object, ce qui oblige d'ailleurs à caster quand on
veut utiliser l'objet.
Je pense que l'on n'est pas d'accord sur le terme "implémentable". Pour
moi, un conteneur typé n'est pas implémentable en Java (sauf
introduction des génériques), alors que pour toi, il est implémenta ble,
mais il faut caster. Le fait de devoir caster (et le fait aussi que le
contenu doive dériver d'une classe de base) n'est pas pour moi un dét ail
annexe, mais un aspect fondamental.
Donc, pour moi, dans ce cas, le polymorphisme dynamique ne
résoud pas le problème. Les templates le résolvent.
Et comme je l'ai déjà dit, quasiment tout ce qu'on peut implément er avec
les templates peut s'implémenter avec le polymorphisme.
Comment ils feraient sinon les langages objet sans templates pour faire
des choses similaires ? En Java par exemple, les conteneurs sont en fait
des conteneurs de Object, ce qui oblige d'ailleurs à caster quand on
veut utiliser l'objet.
Je pense que l'on n'est pas d'accord sur le terme "implémentable". Pour
moi, un conteneur typé n'est pas implémentable en Java (sauf
introduction des génériques), alors que pour toi, il est implémenta ble,
mais il faut caster. Le fait de devoir caster (et le fait aussi que le
contenu doive dériver d'une classe de base) n'est pas pour moi un dét ail
annexe, mais un aspect fondamental.
Donc, pour moi, dans ce cas, le polymorphisme dynamique ne
résoud pas le problème. Les templates le résolvent.
Je sais a peut pret parler des mecanismes C++. Ses paradigmes,
ca commence a devenir plus difficile. Differencer les paradigmes clef
des paradigmes secondaire, ca devient plus subtil, et si on commence
a argumenter en utilisant l'obligation de mot-clef, ca devient
trop lourd.
J'utilise pourtant le terme 'clé' depuis le début.
Je sais a peut pret parler des mecanismes C++. Ses paradigmes,
ca commence a devenir plus difficile. Differencer les paradigmes clef
des paradigmes secondaire, ca devient plus subtil, et si on commence
a argumenter en utilisant l'obligation de mot-clef, ca devient
trop lourd.
J'utilise pourtant le terme 'clé' depuis le début.
Je sais a peut pret parler des mecanismes C++. Ses paradigmes,
ca commence a devenir plus difficile. Differencer les paradigmes clef
des paradigmes secondaire, ca devient plus subtil, et si on commence
a argumenter en utilisant l'obligation de mot-clef, ca devient
trop lourd.
J'utilise pourtant le terme 'clé' depuis le début.
Ce code n'a pas de virtual, poutant l'appel f(b) utilise le
polymorphisme "implicite" comme vous le qualifiez. Si vous n'en etes
pas convaincu, changez "struct B : A" en "class B : A" et ca ne
compile plus...
L'OBP c'est l'OOP sans l'héritage, et donc sans le polymorphisme.
Quel est donc l'apport de votre commentaire, si ce n'est dire qu'on n'a
pas besoin des fonctions virtuelles pour voir apparaître certaines
caractéristiques du polymorphisme ?
Le fait que les fonctions virtuelles ne soient pas activées par
défaut > montrent bien l'intention de faire de la programmation orientée
Je vais donc répéter.
Le programmation orientée objet n'est pas un paradigme clé de C++. La
programmation basée objet, si.
Ensuite la POO ne se restreint pas au polymorphisme. L'encapsulation
est probablement le premier concept introduit en POO et certain
langages se revendiquent OO a travers leur systeme de module.
L'encapsulation est une fonctionnalité du OBP, pas du OOP.
Ça ne passe pas par l'héritage.
Ce code n'a pas de virtual, poutant l'appel f(b) utilise le
polymorphisme "implicite" comme vous le qualifiez. Si vous n'en etes
pas convaincu, changez "struct B : A" en "class B : A" et ca ne
compile plus...
L'OBP c'est l'OOP sans l'héritage, et donc sans le polymorphisme.
Quel est donc l'apport de votre commentaire, si ce n'est dire qu'on n'a
pas besoin des fonctions virtuelles pour voir apparaître certaines
caractéristiques du polymorphisme ?
Le fait que les fonctions virtuelles ne soient pas activées par
défaut > montrent bien l'intention de faire de la programmation orientée
Je vais donc répéter.
Le programmation orientée objet n'est pas un paradigme clé de C++. La
programmation basée objet, si.
Ensuite la POO ne se restreint pas au polymorphisme. L'encapsulation
est probablement le premier concept introduit en POO et certain
langages se revendiquent OO a travers leur systeme de module.
L'encapsulation est une fonctionnalité du OBP, pas du OOP.
Ça ne passe pas par l'héritage.
Ce code n'a pas de virtual, poutant l'appel f(b) utilise le
polymorphisme "implicite" comme vous le qualifiez. Si vous n'en etes
pas convaincu, changez "struct B : A" en "class B : A" et ca ne
compile plus...
L'OBP c'est l'OOP sans l'héritage, et donc sans le polymorphisme.
Quel est donc l'apport de votre commentaire, si ce n'est dire qu'on n'a
pas besoin des fonctions virtuelles pour voir apparaître certaines
caractéristiques du polymorphisme ?
Le fait que les fonctions virtuelles ne soient pas activées par
défaut > montrent bien l'intention de faire de la programmation orientée
Je vais donc répéter.
Le programmation orientée objet n'est pas un paradigme clé de C++. La
programmation basée objet, si.
Ensuite la POO ne se restreint pas au polymorphisme. L'encapsulation
est probablement le premier concept introduit en POO et certain
langages se revendiquent OO a travers leur systeme de module.
L'encapsulation est une fonctionnalité du OBP, pas du OOP.
Ça ne passe pas par l'héritage.
Mathias Gaunard wrote:C'est plus ou moins comme ceci que fonctionnent tous les langages
"objet" qui dérivent tous leurs types d'un type abstrait unique.
Je ne le crois pas. C'était le cas de Smalltalk, mais ce n'est
pas comme ça qu'on écrit en Java, ni en C++, ni en n'importe
quel langage OO moderne.
Mathias Gaunard wrote:
C'est plus ou moins comme ceci que fonctionnent tous les langages
"objet" qui dérivent tous leurs types d'un type abstrait unique.
Je ne le crois pas. C'était le cas de Smalltalk, mais ce n'est
pas comme ça qu'on écrit en Java, ni en C++, ni en n'importe
quel langage OO moderne.
Mathias Gaunard wrote:C'est plus ou moins comme ceci que fonctionnent tous les langages
"objet" qui dérivent tous leurs types d'un type abstrait unique.
Je ne le crois pas. C'était le cas de Smalltalk, mais ce n'est
pas comme ça qu'on écrit en Java, ni en C++, ni en n'importe
quel langage OO moderne.
Le fait que les fonctions virtuelles ne soient pas activées par défaut
montrent bien l'intention de faire de la programmation orientée objet
une fonctionnalité à part.
Le fait que les fonctions virtuelles ne soient pas activées par défaut
montrent bien l'intention de faire de la programmation orientée objet
une fonctionnalité à part.
Le fait que les fonctions virtuelles ne soient pas activées par défaut
montrent bien l'intention de faire de la programmation orientée objet
une fonctionnalité à part.
Je crois
que dans mes applications .NET (principalement de l'IHM, avec les
classes de base, plus deux biblitohèques externes, mais toutes sont
comparables en l'occurence), je me retrouve à faire du downcast depuis
Objet [..] vers le type que je manipule directement.
Je crois
que dans mes applications .NET (principalement de l'IHM, avec les
classes de base, plus deux biblitohèques externes, mais toutes sont
comparables en l'occurence), je me retrouve à faire du downcast depuis
Objet [..] vers le type que je manipule directement.
Je crois
que dans mes applications .NET (principalement de l'IHM, avec les
classes de base, plus deux biblitohèques externes, mais toutes sont
comparables en l'occurence), je me retrouve à faire du downcast depuis
Objet [..] vers le type que je manipule directement.