OVH Cloud OVH Cloud

La fin de l'héritage ?

103 réponses
Avatar
Olivier Azeau
J'ai lu avec grand intérêt l'article "Concepts for C++0x" mentionné dans
un thread récent.
Habituellement, je ne m'intéresse pas aux évolutions du langage car
elles ne me concernent qu'à un relativement long terme, mais là, j'ai
l'impression qu'un mouvement de fond relatif aux paradygmes du C++ prend
une certaine ampleur.
Et ce mouvement m'amène à quelques interrogations.

La plupart des développeurs que je cotoie programment en C++ dans un
style orienté objet très proche de ce que l'on trouve en Java.

Je prends un exemple classique de Bridge+Factory pour illustrer mon propos.
On a typiquement une hiérarchie d'implémentations :
| class DocumentDisplay {
| virtual ~DocumentDisplay();
| virtual void drawText( int x, int y, std::string const &text ) = 0;
| virtual void drawLine( int x1, int y1, int x2, int y2 ) = 0;
| };
|
| class GraphicDocumentDisplay : public DocumentDisplay {
| virtual void drawText( int x, int y, std::string const &text );
| virtual void drawLine( int x1, int y1, int x2, int y2 );
| };
|
| class TextDocumentDisplay : public DocumentDisplay {
| ...

une hiérarchie d'abstractions qui utilisent les implémentations :
|
| class Document {
| public:
| Document( DocumentDisplay *display ) : display_(display) {}
| virtual ~Document();
|
| void drawFrame( int x, int y, int w, int h, std::string const &title ) {
| display_->drawLine( x, y, x+w, y );
| display_->drawLine( x, y+h, x+w, y+h );
| display_->drawText( x, y, title );
| }
| private:
| DocumentDisplay *display_;
| };
|
| class Memo : public Document {
| public:
| Memo( DocumentDisplay *display ) : Document(display) {}
| void drawSummary() { drawFrame( 0, 0, 150, 100, "Summary" ); }
| };
|
| class Invoice : public Document {
| ...

une hiérarchie de fabriques pour instancier tout ça :
| class DocumentFactory {
| public:
| virtual ~DocumentFactory() {}
| virtual Memo *createMemo() = 0;
| virtual Invoice *createInvoice() = 0;
| };
|
| class GraphicDocumentFactory : public DocumentFactory {
| public:
| virtual Memo *createMemo() { return new Memo( new
GraphicDocumentDisplay ); }
| virtual Invoice *createInvoice() { return new Invoice( new
GraphicDocumentDisplay ); }
| };

et je rajoute un programme principal pour utiliser le tout :
| class Application {
| public:
| Application( DocumentFactory *factory ) : factory_(factory) {}
|
| void run() {
| Memo *memo = factory_->createMemo();
| memo->drawSummary();
| }
| private:
| DocumentFactory *factory_;
| };
|
| int main() {
| Application app( new GraphicDocumentFactory );
| app.run();
| }

En pratique, ça a une tête un peu différente (avec le RAII par exemple),
mais l'idée des hiérarchie de classes est là.

Depuis quelques temps se répand la programmation générique qui permet de
faire la même chose avec (en général) moins de lignes de code.

Les implémentations deviennent des "policy" et n'ont plus besoin de
classe de base
| class GraphicDocumentDisplay {
| virtual void drawText( int x, int y, std::string const &text );
| virtual void drawLine( int x1, int y1, int x2, int y2 );
| };

Les abstractions sont paramétrées par la policy.
On garde un héritage pour partager l'implémentation :
| template <class DOCDISP>
| class Document {
| public:
| virtual ~Document() {}
|
| void drawFrame( int x, int y, int w, int h, std::string const &title ) {
| display_.drawLine( x, y, x+w, y );
| display_.drawLine( x, y+h, x+w, y+h );
| display_.drawText( x, y, title );
| }
| private:
| DOCDISP display_;
| };
|
| template <class DOCDISP>
| class Memo : public Document<DOCDISP> {
| public:
| void drawSummary() { drawFrame( 0, 0, 150, 100, "Summary" ); }
| };

Dans un cas aussi simple, on oublie la factory et on paramètre
directement l'application :
| template <class DOCDISP>
| class Application {
| public:
| void run() {
| Memo<DOCDISP> memo;
| memo.drawSummary();
| }
| };
|
| int main() {
| Application<GraphicDocumentDisplay> app;
| app.run();
| }

Une telle approche est actuellement plutôt prisée par des personnes qui
connaissent bien le langage et est donc globalement plutôt minoritaire.
Parmi les raisons de cette situation je vois :
- la forte présence de langages comme Java ou C# qui ne proposent pas
cette approche (les versions "Generic" restent anecdotiques) et donc le
grand nombre de personnes qui font du C++ comme ils font du Java
- le faible support des templates par certains compilateurs jusqu'à une
période récente (cf les interrogations récurrentes relatives au support
des templates dans VC6)
- un support méthodologique peu adapté (UML se prête beaucoup plus à
décrire des héritages que de paramétrages)
- une complexité de mise au point d'une approche à base de templates
(typage structurel, définitions statiques, ...)

Sur ce, je découvre les "concepts" (dont je ne pense pas avoir saisi le
dixième des utilisations et implications) qui me laissent supposer que,
dans un avenir plus ou moins proche, on pourrait écrire les choses de
manière plus explicites.

Les policy pourraient être nommées et contrôlées avant usage. Si j'ai
bien compris les notions et syntaxes proposées dans l'article, cela
donnerait quelque chose comme :
| template <DOCDISP>
| concept DisplaysDocuments {
| void DOCDISP::drawText( int x, int y, std::string const &text );
| void DOCDISP::drawLine( int x1, int y1, int x2, int y2 );
| };
|
| class GraphicDocumentDisplay {
| public:
| void drawText( int x, int y, std::string const &text );
| void drawLine( int x1, int y1, int x2, int y2 );
| };
|
| model DisplaysDocuments<GraphicDocumentDisplay>;

| template <class DOCDISP>
| class Application where { DisplaysDocuments<DOCDISP> } {
| public:
| void run() {
| Memo<DOCDISP> memo;
| memo.drawSummary();
| }
| };

Et j'ai même l'impression que des implémentations par défaut définies au
niveau des concepts pourraient rendre obsolète une grand pan de
l'utilisation de l'héritage.

En écrivant par exemple ce qui suit, j'ai l'impression d'avoir
entièrement réécrit l'exemple vu précédemment sans utiliser aucun
héritage C++ mais avec l'impression d'avoir quand même fait de l'"objet"
(s'il est encore possible de définir ce terme...) mais "autrement".
| template <DOC>
| concept IsDocument {
| typename doc_display;
| require DisplaysDocuments<doc_display>;
|
| doc_display &DOC::display();
|
| void DOC::drawFrame( int x, int y, int w, int h, std::string const
&title ) {
| display().drawLine( x, y, x+w, y );
| display().drawLine( x, y+h, x+w, y+h );
| display().drawText( x, y, title );
| }
| };
|
| template <class DOCDISP>
| class Memo {
| public:
| typedef DOCDISP doc_display;
| doc_display &display() { return display_; }
|
| void drawSummary() { drawFrame( 0, 0, 150, 100, "Summary" ); }
| private:
| DOCDISP display_;
| };
|
| template <class DOCDISP>
| model IsDocument< Memo<DOCDISP> >;

Pour ceux qui auront eu le courage de lire jusqu'ici, j'aimerais savoir
s'ils pensent :
- que je n'ai rien compris aux "concepts" ?
- que ces notions vont avoir un impact technique majeur sur l'écriture
de code en C++ ?
- que ces notions vont avoir un impact sociologique majeur sur le
développement en C++ ?

Je suis plus particulièrement intéressé par l'aspect sociologique des
choses.
J'ai l'impression d'être face à une évolution du même ordre de grandeur
que le passage du C au C++.
Pour tout dire, j'ai même l'impression que le terme C++ n'est conservé
que pour des raisons marketing (la "marque" est déja connue, appréciée,
possède une base de consommateurs, ...)

Il est toujours possible d'écrire du C avec un compilateur C++ mais, sur
une période d'environ 10 ans (en gros les années 90) on est passé d'une
approche majoritaire en termes de structures/procédures a une approche
majoritaire classes/héritages/associations.
Cela a impliqué un changement de principes de modélisation, un
changement de techniques d'écriture de code mais surtout un changement
de mentalité.
Et quand je regarde les efforts qu'il a fallu déployer pour que
l'ensemble des intervenants en arrive à penser les développements plus
ou moins de la même manière, j'ai un peu l'impression, en voyant ces
nouvelles notions qui se profilent à l'horizon, que nous ne sommes pas
au bout de nos peines...

10 réponses

1 2 3 4 5
Avatar
Olivier Azeau
xavier wrote:
Je ne suis pas entièrement d'accord avec ceci, le but du système
est, il

me semble, de rendre explicite les contraintes imposées par un
concept,

pas de les masquer pour l'utilisateur final.


Ok (je suis loin d'avoir lu tout ce qui se dit sur le sujet)

Moi ca me semblait naturel d'avoir plusieurs niveaux d'informations :
- avoir le détail des contraintes pour celui qui développe un classe
et déclare qu'elle modélise un certain concept
- avoir seulement l'information du concept manquant pour celui qui
instancie un template dont un parametre doit modeliser un concept donné

Avatar
Loïc Joly
Olivier Azeau wrote:

J'ai l'impression que les concepts "habillent" la programmation
générique en C++ tout comme le C++ a habillé la programmation objet
en C.


Je suis assez d'accord. J'hésiterais juste entre cette comparaison et
celle qui consisterait à dire que les concepts sont à la programmation
générique ce que le typage fort est à la programmation.

--
Loïc

Avatar
kanze
Jean-Marc Bourguet wrote:
"Olivier Azeau" writes:

Pour un projet donné, faudra-t-il imposer une approche ?


Le polymorphisme parametrique (la genericite) et le
polymorphisme de substitution (celui qui resulte de
l'heritage) ont des domaines d'application differents mais qui
se recoupent un peu.


Très peu, en fait.

Oui la mode pour le moment est d'utiliser plutot le premier
que le second.


Ça dépend où. Dans les groupes de news, la mode est vraiment à
le polymorphisme paramètrique. Dans l'industrie, j'ai
l'impression qu'il y a encore beaucoup de boîtes que ne le
connaissent pas, et où la mode est au polymorphisme de
substitution.

En général, chaque fois que le choix se base sur une mode, c'est
mauvais signe:-). L'exemple initial, par exemple, me semblait un
cas où l'héritage a de nets avantages.

Mais je ne suis pas sûr que ça change quelque chose du fond. Je
n'ai pas trop suivi les histoires de « concepts », mais est-ce
qu'il ne serait pas un peu une façon de définir des contrats
pour le polymorphisme paramètrique ?

--
James Kanze GABI Software http://www.gabi-soft.fr
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34


Avatar
Ivan Vecerina
"Olivier Azeau" wrote in message
news:
|> Il faut noter comme le résultat est différent: la version OO
|> produit
|> une application qui par l'intermédiaire de la Factory
|> pouvait créer un type de document ou l'autre.
|> Plus de flexibilitté, avec un certain
|> coût en terme de performance (pas significatif ici).
|> Avec la version générique, on compile soit un type
|> d'application, soit l'autre, à partir du même code.

|Je ne comprends pas. Je peux également choisir dynamiquement le type
|d'affichage avec la version template :
|| int main() {
|| if( graphicDisplayIsAvailable() ) {
|| Application<GraphicDocumentDisplay> app;
|| app.run();
|| } else {
|| Application<TextDocumentDisplay> app;
|| app.run();
|| }
|| }

Oui, mais ce qu'il faut regarder est quelle portion du code
est commune entre les deux versions du document:


Version OO:
+----------> GraphicDisplay
Document ----+ (dispatch dynamique en run-time)
+----------> Text Display
Il n'existe qu'une version du code de 'Document'.



Version Générique (template simple ou concept):

DocumentGraphique -----------> GraphicDisplay

DocumentTexte -----------> TextDisplay

Le code de 'Document' est intégralement dupliqué.
Ceci peut apporter un gain de performance à l'exécution
en au coût d'une quantité de code supplémentaire. Un gain
aussi si seulement un des deux types de documents doit
être compilé dans une application.

|> Il me semble que les concepts ne changent rien en terme du
|> code qui peut être généré. Il s'agit surtout de rendre l'usage
|> des templates plus lisible et aisée (ce qui a son importance).
|
|Mais justement, est-ce que la problematique du choix de l'approche
|n'est pas principalement due aux difficultés de mise en oeuvre du
|"polymorphisme de compilation" dans l'état actuel des templates ?

Dans certains cas peut-être. Le choix d'une forme de polymorphisme
ou de l'autre devrait avant tout dépendre de critères de design
et de performance. L'orienté-objet dynamique total (pex SmallTalk)
permet de tout faire, mais a des coût excessifs en terme de
performance. (C'est pourquoi, en Java, int/etc ne sont pas
des objets). D'ou la puissance d'un polymorphisme traduit
en phase de compilation (= programmation générique).

Le fait que la programmation générique devienne plus accessible
pourrait permettre un choix plus libre entre ces deux niveaux
de polymorphisme.

|> Les concepts peuvent sembler similaires à de l'orienté-objet.
|> En fait ils sont juste un habillage différent des templates AMHA.
|
|Le terme habillage me parait réducteur.
|J'ai l'impression que les concepts "habillent" la programmation
|générique en C++ tout comme le C++ a habillé la programmation objet
|en C.

Il est clair que bien qu'on puisse faire de l'orienté-objet en C,
cela ne réduit pas la valeur du support et de l'"habillage" donné
en C++ à cette technique de programmation.
Je pense que la question est plutôt si ces "concepts" sont ou
nom une bonne manière, et *la* bonne manière, d'offrir un
meilleur support pour la programmation générique dans le language.

|> Je pense simplement que le C++ est un language complexe car il
|> intègre nombre de
|> concepts et de paradigmes de programmation. Ceci le rend
|> puissant, mais aussi complexe et plus difficile à aborder.
|
|Ok. Donc en rajoutant de nouvelles notions qui simplifient une
|certaine approche du développement, on complexifie la mise en
|oeuvre d'une utilisation de C++.

Exactement.
Une meilleure intégration d'autres paradigmes (p.ex.
programmation fonctionnelle, introspection, etc) est
également envisagée en C++. Il serait judicieux de
trouver une approche et une syntaxe unifiée pour
intégrer tous ces paradigmes (et qui soit un peu
moins barbare que les templates actuels...).

--
http://ivan.vecerina.com/contact/?subject=NG_POST <- email contact form
Avatar
Jean-Marc Bourguet
writes:

Jean-Marc Bourguet wrote:
"Olivier Azeau" writes:

Pour un projet donné, faudra-t-il imposer une approche ?


Le polymorphisme parametrique (la genericite) et le polymorphisme
de substitution (celui qui resulte de l'heritage) ont des domaines
d'application differents mais qui se recoupent un peu.


Très peu, en fait.


Il y a pas mal de chose que tu peux faire en utilisant le
polymorphisme de substitution a la place du polymorphisme
parametrique. Avec plus de travail (il faut parfois faire des
adaptateurs) et en perdant parfois le controle de type.

Oui la mode pour le moment est d'utiliser plutot le premier que le
second.


Ça dépend où. Dans les groupes de news, la mode est vraiment à le
polymorphisme paramètrique.


C'est certain.

Dans l'industrie, j'ai l'impression qu'il y a encore beaucoup de
boîtes que ne le connaissent pas, et où la mode est au polymorphisme
de substitution.


Je n'ai pas une bonne vision de l'industrie en general. Je n'ai meme
pas une bonne vision de ce que font les autres divisions de ma boite
en la matiere. Et le projet sur lequel je travaille pour le moment
est en train de faire le passage C -> C++...

Ma perception est que la mode est en train de s'etendre au dela des
news et des cercles "inities", mais je peux me tromper.

En général, chaque fois que le choix se base sur une mode, c'est
mauvais signe:-). L'exemple initial, par exemple, me semblait un cas
où l'héritage a de nets avantages.


A moi aussi. J'ai commence une reponse mais n'ai pas reellement le
temps de la finir. Mais j'ai deja des problemes avec la conception
initiale (drawFrame ne me semble pas devoir etre un membre de
Document).

Mais je ne suis pas sûr que ça change quelque chose du fond. Je n'ai
pas trop suivi les histoires de « concepts », mais est-ce qu'il ne
serait pas un peu une façon de définir des contrats pour le
polymorphisme paramètrique ?


Ca depend ce que tu entends par contrats. C'est une facon de
specifier les contraintes que doivent respecter les arguments
templates et ca permet au moins d'une part de verifier que le code
template n'utilise pas autre chose, d'autre part de verifier que les
clients respectent bien ces contraintes meme si pour le moment elles
ne sont pas utilisees. En prime ca doit permettre de generer des
messages d'erreurs plus comprehensible. Je n'ai pas encore compris
comment ca permet de faciliter l'ecriture de template -- en
particulier l'allusion a SFINAE) sauf si on essaie de faire mon
deuxieme point (verifier que le code utilisateur respecte les
contraintes) avec les possibilites actuelles.

A partir du moment ou on nomme des contraintes, on peut les reutiliser
(ce qui n'est pas possible avec une autre technique possibe: etendre
les parametres templates pour pouvoir y mettre avec des valeurs par
defaut tout ce qui est utilise) et les manipuler. Je ne sais pas
quelles seront les manipulations permises (les valeurs par defaut) ni
ce qu'elles apporteront. On peut avoir une "surprise" du genre de
celle apportee par le fait que les templates sont deja un langage
complet et donc autre chose que des macros avec du typage fort. J'ai
l'impression que l'approche de Gaby et Bjarne est d'explorer justement
les differentes solutions pour choisir la plus coherente et la plus
expressive.

A+

--
Jean-Marc
FAQ de fclc++: http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ
C++ FAQ Lite en VF: http://www.ifrance.com/jlecomte/c++/c++-faq-lite/index.html
Site de usenet-fr: http://www.usenet-fr.news.eu.org



Avatar
Gabriel Dos Reis
writes:

| Jean-Marc Bourguet wrote:
| > "Olivier Azeau" writes:
|
| > > Pour un projet donné, faudra-t-il imposer une approche ?
|
| > Le polymorphisme parametrique (la genericite) et le
| > polymorphisme de substitution (celui qui resulte de
| > l'heritage) ont des domaines d'application differents mais qui
| > se recoupent un peu.
|
| Très peu, en fait.
|
| > Oui la mode pour le moment est d'utiliser plutot le premier
| > que le second.
|
| Ça dépend où. Dans les groupes de news, la mode est vraiment à
| le polymorphisme paramètrique.

« Usenet is a strange place » -- dmr

| Dans l'industrie, j'ai
| l'impression qu'il y a encore beaucoup de boîtes que ne le
| connaissent pas, et où la mode est au polymorphisme de
| substitution.

mais, d'après mon expérience, c'est une fausse dichotomie.
La vérité se trouve ailleurs.

|
| En général, chaque fois que le choix se base sur une mode, c'est
| mauvais signe:-). L'exemple initial, par exemple, me semblait un
| cas où l'héritage a de nets avantages.
|
| Mais je ne suis pas sûr que ça change quelque chose du fond. Je
| n'ai pas trop suivi les histoires de « concepts », mais est-ce
| qu'il ne serait pas un peu une façon de définir des contrats
| pour le polymorphisme paramètrique ?

Des types/relations pour les paramètres/arguments de
templates. Je n'appelerais pas ça un « contrat » mais bon, ce n'est
pas une question de mots.
L'école d'Indiana parle de constraintes, mais c'est parce
qu'elle est fortement dominée par la théorie des itérateurs :-)
Dès qu'on en sort un peu, on se rend compte parler uniquement de
contraintes est un peu réducteur. Nous avions essayé d'expliquer cela
dans les premiers papiers.

-- Gaby
Avatar
Gabriel Dos Reis
Jean-Marc Bourguet writes:

[...]

| Ma perception est que la mode est en train de s'etendre au dela des
| news et des cercles "inities", mais je peux me tromper.

oui, malheureusement sans voir le fond de l'histoire :-(
je vois de plus en plus de policy partout avec des myriades de
paramètres et des smart pointers dans tous les coins, même et surtout
là où n'est pas pertinent.
:-(

[...]

| > Mais je ne suis pas sûr que ça change quelque chose du fond. Je n'ai
| > pas trop suivi les histoires de « concepts », mais est-ce qu'il ne
| > serait pas un peu une façon de définir des contrats pour le
| > polymorphisme paramètrique ?
|
| Ca depend ce que tu entends par contrats. C'est une facon de
| specifier les contraintes que doivent respecter les arguments
| templates et ca permet au moins d'une part de verifier que le code
| template n'utilise pas autre chose, d'autre part de verifier que les
| clients respectent bien ces contraintes meme si pour le moment elles
| ne sont pas utilisees. En prime ca doit permettre de generer des
| messages d'erreurs plus comprehensible. Je n'ai pas encore compris
| comment ca permet de faciliter l'ecriture de template -- en
| particulier l'allusion a SFINAE) sauf si on essaie de faire mon
| deuxieme point (verifier que le code utilisateur respecte les
| contraintes) avec les possibilites actuelles.

Surcharger les templates. Actuellement, on ne peut le faire que pour
les fonctions et sur nombre de paramètres. SFINEA permet une
approximation, mais uniquement au prix d'une obfuscation redoutable.
Nombre d'algorithmes de la stl se terminent pas _if parce qu'on ne
sait pas exprimer le fait que quelque chose est un predicat et l'autre
juste une valeur (que l'on cherche).


|
| A partir du moment ou on nomme des contraintes, on peut les reutiliser
| (ce qui n'est pas possible avec une autre technique possibe: etendre
| les parametres templates pour pouvoir y mettre avec des valeurs par
| defaut tout ce qui est utilise) et les manipuler. Je ne sais pas
| quelles seront les manipulations permises (les valeurs par defaut) ni
| ce qu'elles apporteront. On peut avoir une "surprise" du genre de
| celle apportee par le fait que les templates sont deja un langage
| complet et donc autre chose que des macros avec du typage fort. J'ai
| l'impression que l'approche de Gaby et Bjarne est d'explorer justement
| les differentes solutions pour choisir la plus coherente et la plus
| expressive.

Exact.

Nous avons essayé de trouver des exemples « tests ». Par exemple,
essayer d'exprimer merge() correctement, ou essayer de modeliser
des structures mathématiques -- pour ne pas s'enfermer dans le
monde des itérateurs.
Une solution qui passerait ces exemples test est prometteuse.

-- Gaby
Avatar
Gabriel Dos Reis
"Ivan Vecerina" writes:

[...]

| |Ok. Donc en rajoutant de nouvelles notions qui simplifient une
| |certaine approche du développement, on complexifie la mise en
| |oeuvre d'une utilisation de C++.
|
| Exactement.
| Une meilleure intégration d'autres paradigmes (p.ex.
| programmation fonctionnelle, introspection, etc) est
| également envisagée en C++. Il serait judicieux de
| trouver une approche et une syntaxe unifiée pour
| intégrer tous ces paradigmes (et qui soit un peu
| moins barbare que les templates actuels...).

100% d'accord. Nous avons compté qu'il y a en gros une dizaine de
propositions qui affectent la notion de constructeur, il faut les
unifier.

On parle souvent de lambda. Peu de gens voient qu'ils sont liés aux
histoires de constantes généralisées (un type n'est qu'une constante,
de même pour le corps d'une fonction) et qu'il vaut mieux trouver une
approche unifiée et cohérente. En général, on a tendance à vouloir une
extension qui résoud exactement le problème sous la main, pas une
approche générale.

-- Gaby
Avatar
Jean-Marc Bourguet
Gabriel Dos Reis writes:

Jean-Marc Bourguet writes:

[...]

| Ma perception est que la mode est en train de s'etendre au dela des
| news et des cercles "inities", mais je peux me tromper.

oui, malheureusement sans voir le fond de l'histoire :-(


Je crois que plus que de capacites nouvelles en C++, ce dont certains
manquent est une connaissance d'autres langages (et Java et C# ne
comptent pas).

je vois de plus en plus de policy partout avec des myriades de
paramètres et des smart pointers dans tous les coins, même et
surtout là où n'est pas pertinent.


La maniere dont l'OP a utilise "policy" est assez revelatrice de ca.
J'aimerais avoir le temps de repondre au premier message en detail...

L'attitude "tout pointeur non smart devrait etre supprime en dehors de
l'implementation des smart pointeurs" devient aussi parfois penible.

[...]
| Je n'ai pas encore compris
| comment ca permet de faciliter l'ecriture de template -- en
| particulier l'allusion a SFINAE) sauf si on essaie de faire mon
| deuxieme point (verifier que le code utilisateur respecte les
| contraintes) avec les possibilites actuelles.

Surcharger les templates.


Ok, j'ai compris.

A+

--
Jean-Marc
FAQ de fclc++: http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ
C++ FAQ Lite en VF: http://www.ifrance.com/jlecomte/c++/c++-faq-lite/index.html
Site de usenet-fr: http://www.usenet-fr.news.eu.org

Avatar
kanze
Jean-Marc Bourguet wrote:
writes:

Jean-Marc Bourguet wrote:
"Olivier Azeau" writes:

Pour un projet donné, faudra-t-il imposer une approche ?


Le polymorphisme parametrique (la genericite) et le
polymorphisme de substitution (celui qui resulte de
l'heritage) ont des domaines d'application differents mais
qui se recoupent un peu.


Très peu, en fait.


Il y a pas mal de chose que tu peux faire en utilisant le
polymorphisme de substitution a la place du polymorphisme
parametrique. Avec plus de travail (il faut parfois faire des
adaptateurs) et en perdant parfois le controle de type.


Il y a souvent des choses qu'on *peut* faire. Mais dans la
plupart des cas (non tous, mais prèsque), une des solutions
s'impose ; l'autre, c'est plutôt « on pourrait le faire s'il n'y
avait pas d'alternatif ».

Oui la mode pour le moment est d'utiliser plutot le
premier que le second.


Ça dépend où. Dans les groupes de news, la mode est vraiment
à le polymorphisme paramètrique.


C'est certain.

Dans l'industrie, j'ai l'impression qu'il y a encore
beaucoup de boîtes que ne le connaissent pas, et où la mode
est au polymorphisme de substitution.


Je n'ai pas une bonne vision de l'industrie en general. Je
n'ai meme pas une bonne vision de ce que font les autres
divisions de ma boite en la matiere. Et le projet sur lequel
je travaille pour le moment est en train de faire le passage C
-> C++...


Ma vision de l'industrie est un peu conditionnée par les
démandes d'emploi et mes entretiens d'embauche. Or, les mêmes
thèmes restent primordiaux. Dans les entretiens, par exemple, il
y a toujours des questions sur des modèles de conception, et les
modèles de conception qui semblent intéresser le plus, ce sont
ceux où il y a la substitution polymorphique.

Mais un intérêt pour la générique se pointe. Pour l'instant, je
dirais que c'est plutôt avec un oeil pour la future, plutôt que
ce qu'on fait actuellement, mais ça arrive. (Il faut dire aussi
que dans les milieux que je fréquente, les compilateurs
« standard » reste Sun CC, g++ 2.95 et VC++ 6.0. Alors, les
essais d'une programmation générique poussée sont à exclure.
Mais là aussi, il y a évolution, et g++ 3.[34] se répand.)

Ma perception est que la mode est en train de s'etendre au
dela des news et des cercles "inities", mais je peux me
tromper.


Il s'étend, c'est sûr. À quelle vitesse, c'est une autre
question.

En général, chaque fois que le choix se base sur une mode,
c'est mauvais signe:-). L'exemple initial, par exemple, me
semblait un cas où l'héritage a de nets avantages.


A moi aussi. J'ai commence une reponse mais n'ai pas
reellement le temps de la finir. Mais j'ai deja des problemes
avec la conception initiale (drawFrame ne me semble pas devoir
etre un membre de Document).

Mais je ne suis pas sûr que ça change quelque chose du
fond. Je n'ai pas trop suivi les histoires de « concepts »,
mais est-ce qu'il ne serait pas un peu une façon de définir
des contrats pour le polymorphisme paramètrique ?


Ca depend ce que tu entends par contrats.


Je pensais au sens le plus large.

C'est une facon de specifier les contraintes que doivent
respecter les arguments templates et ca permet au moins d'une
part de verifier que le code template n'utilise pas autre
chose, d'autre part de verifier que les clients respectent
bien ces contraintes meme si pour le moment elles ne sont pas
utilisees.


C'est à peu près ça que j'entendais par « contrat ».

--
James Kanze GABI Software http://www.gabi-soft.fr
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34




1 2 3 4 5