Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Bibliothèque [niveau débutant]

16 views
Skip to first unread message

lionmarron

unread,
Nov 22, 2011, 4:06:48 PM11/22/11
to
Je ne suis pas sûr d'être forcément sur les bons forums : ma
problématique (ma question autrement dit) pourrait être toutefois
relative au langages de programmations en général, plus précisément aux
langages de programmations actuels, et par conséquent aux langages
orientés objet.

Pour éviter de parler d'une façon abstraite, je précise que, dans le
contexte, le langage que je tente d'utiliser est python (version 2.7).

Ce que fait mon programme n'a en revanche pas d'importance : il s'agit
avant tout de faire des essais et par conséquent c'est quelque chose de
facile à faire. Lorsque je découvre un nouveau langage de programmation
je programme toujours un jeu d'échecs, ce qui est donc le cas ici,
toutefois il s'agira seulement de savoir si un déplacement est légal ou
non, pas de juger de la valeur d'un coup. Il y a qq décennies je pouvais
faire ça (et d'autres pouvaient faire plus) avec 32 K de ram.

Étant donné qu'il faut malgré tout une certaine longueur de listing pour
savoir si un coup est légal ou non, je voudrais mettre ce qui fait ça
dans une partie externe du programme, et c'est là que se trouve le fond
du problème, ou en tout cas ce qui constitue le sujet de ce message.

Peut-on faire une bibliothèque normale (quelque chose de normalement
compréhensible pour un cerveau normal et pour un simple mortel), ou bien
faut-il nécessairement faire une classe ?

Ma principale référence est le livre de Swinnen <Apprendre à programmer
avec Python> , édition 2005 (O'Reilly). D'après ce livre on pourrait
penser qu'il n'y a pas d'autre moyens que de créer un classe, toutefois
ce n'est pas dit explicitement, alors autant être sûr.

Je précise que la question que je pose (ou que je cherche à soulever)
n'est pas de savoir si les langages orienté objet sont mieux ou moins
bien que ce qu'on faisait avant. On aura peut-être compris que, de mon
point de vue, ce qui relève de ce mode de programmation n'est pas <
furieusement très clair >. Cela étant je me doute bien que si c'est plus
compliqué c'est parce que cela permet sans doute de faire mieux dans
certains cas, même si ce sont des cas que je n'imagine peut-être pas, ou
que j'ai rencontrer sans en percevoir la véritable nature.

Si certains acceptent de me promettre qu'ils ne le répéteront pas, je
veux bien leur concéder que je n'y crois pas réellement, autrement dit
je pense que c'est de la blague. Mais ça je l'ai pas dit, je l'ai
seulement pensé. (Autrement dit si certains ont pu lire ce qui précède
cela signifie qu'ils se trompent : ils ont cru le lire.)

A vos claviers. Et que ça saute. Ça manque d'agitation ici (c'est pas
possible).

Suivi sur fr.comp.algorithmes

--
lionmarron



JKB

unread,
Nov 22, 2011, 4:21:29 PM11/22/11
to
Le Tue, 22 Nov 2011 22:06:48 +0100,
lionmarron <andre....@club-internet.fr> écrivait :

Bonsoir,

C'est toujours mieux de commencer comme ça...

> Je ne suis pas sûr d'être forcément sur les bons forums : ma
> problématique (ma question autrement dit) pourrait être toutefois
> relative au langages de programmations en général, plus précisément aux
> langages de programmations actuels, et par conséquent aux langages
> orientés objet.
>
> Pour éviter de parler d'une façon abstraite, je précise que, dans le
> contexte, le langage que je tente d'utiliser est python (version 2.7).
>
> Ce que fait mon programme n'a en revanche pas d'importance : il s'agit
> avant tout de faire des essais et par conséquent c'est quelque chose de
> facile à faire. Lorsque je découvre un nouveau langage de programmation
> je programme toujours un jeu d'échecs, ce qui est donc le cas ici,
> toutefois il s'agira seulement de savoir si un déplacement est légal ou
> non, pas de juger de la valeur d'un coup. Il y a qq décennies je pouvais
> faire ça (et d'autres pouvaient faire plus) avec 32 K de ram.
>
> Étant donné qu'il faut malgré tout une certaine longueur de listing pour
> savoir si un coup est légal ou non, je voudrais mettre ce qui fait ça
> dans une partie externe du programme, et c'est là que se trouve le fond
> du problème, ou en tout cas ce qui constitue le sujet de ce message.
>
> Peut-on faire une bibliothèque normale (quelque chose de normalement
> compréhensible pour un cerveau normal et pour un simple mortel), ou bien
> faut-il nécessairement faire une classe ?

Je ne parlerai pas de Python que de déteste cordialement (et qui me
le rend bien) pour tout un tas de question objectives (et d'autres
subjectives). Je parle ici dans le cas général. Il est parfaitement
possible d'appeler depuis un langage procédural (ou impératif et
certainement aussi depuis un langage fonctionnel) des bibliothèques
partagées écrites dans un langage objet. Le contraire est vrai
aussi. Pour fixer les idées, on peut très bien appeler depuis le C
des bibliothèques écrites en C++ et depuis le C++, des bibliothèques
écrites en C. Il suffit de se mettre d'accord sur les interfaces.

> Ma principale référence est le livre de Swinnen <Apprendre à programmer
> avec Python> , édition 2005 (O'Reilly). D'après ce livre on pourrait
> penser qu'il n'y a pas d'autre moyens que de créer un classe, toutefois
> ce n'est pas dit explicitement, alors autant être sûr.
>
> Je précise que la question que je pose (ou que je cherche à soulever)
> n'est pas de savoir si les langages orienté objet sont mieux ou moins
> bien que ce qu'on faisait avant. On aura peut-être compris que, de mon
> point de vue, ce qui relève de ce mode de programmation n'est pas <
> furieusement très clair >.s

Ce n'est pas le but. Le but est d'encapsuler des données dans des
objets pour éviter au maximum que le programmateur de base touche à
ce qui peut fâcher comme les allocations explicites de mémoire. La
contrepartie est que c'est lourd et assez souvent write-only lorsque
ce n'est pas documenté correctement. Passer sur un code C++ complexe
non documenté est une gageure, mais je m'égare.

> Cela étant je me doute bien que si c'est plus
> compliqué c'est parce que cela permet sans doute de faire mieux dans
> certains cas, même si ce sont des cas que je n'imagine peut-être pas, ou
> que j'ai rencontrer sans en percevoir la véritable nature.
>
> Si certains acceptent de me promettre qu'ils ne le répéteront pas, je
> veux bien leur concéder que je n'y crois pas réellement, autrement dit
> je pense que c'est de la blague. Mais ça je l'ai pas dit, je l'ai
> seulement pensé. (Autrement dit si certains ont pu lire ce qui précède
> cela signifie qu'ils se trompent : ils ont cru le lire.)
>
> A vos claviers. Et que ça saute. Ça manque d'agitation ici (c'est pas
> possible).

Je crois que j'ai marché dedans...

JKB

--
Si votre demande me parvient sur carte perforée, je titiouaillerai très
volontiers une réponse...
=> http://grincheux.de-charybde-en-scylla.fr

Encolpe Degoute

unread,
Nov 22, 2011, 4:54:08 PM11/22/11
to
Bonjour,


Le 22/11/2011 22:06, lionmarron a écrit :
> [SNIP]
> Je précise que la question que je pose (ou que je cherche à soulever)
> n'est pas de savoir si les langages orienté objet sont mieux ou moins
> bien que ce qu'on faisait avant. On aura peut-être compris que, de mon
> point de vue, ce qui relève de ce mode de programmation n'est pas <
> furieusement très clair >. Cela étant je me doute bien que si c'est plus
> compliqué c'est parce que cela permet sans doute de faire mieux dans
> certains cas, même si ce sont des cas que je n'imagine peut-être pas, ou
> que j'ai rencontrer sans en percevoir la véritable nature.


En fait, je suis là des trolls lancés par des ignorants :
1. Les langages objets sont plus faciles à développer correctement que
les autres parce qu'ils obligent le programmeur à se poser la question
de la structure de donnée et de la portée des variables.
2. Python permet de faire du procédural même si c'est globalement
déconseillé (il permet aussi de faire du lambda calcul)

> Si certains acceptent de me promettre qu'ils ne le répéteront pas, je
> veux bien leur concéder que je n'y crois pas réellement, autrement dit
> je pense que c'est de la blague. Mais ça je l'ai pas dit, je l'ai
> seulement pensé. (Autrement dit si certains ont pu lire ce qui précède
> cela signifie qu'ils se trompent : ils ont cru le lire.)

C'est pareil pour moi : vous avez cru lire une réponse utile mais comme
le but était juste de lancer un discussion je n'en ferai rien.

> A vos claviers. Et que ça saute. Ça manque d'agitation ici (c'est pas
> possible).

Il est aussi possible de faire autre chose que d'aller sur usenet : il
parait que movim et diaspora cherchent à concurrencer facebook. C'est du
PHP vous devriez aimer.

Suivi dans le trou noir de fr.
--
Encolpe DEGOUTE
http://encolpe.degoute.free.fr/
Logiciels libres, hockey sur glace et autres activités cérébrales

JKB

unread,
Nov 22, 2011, 5:23:18 PM11/22/11
to
Le Tue, 22 Nov 2011 22:54:08 +0100,
Encolpe Degoute <encolpe...@free.fr> écrivait :
> Bonjour,
>
>
> Le 22/11/2011 22:06, lionmarron a écrit :
>> [SNIP]
>> Je précise que la question que je pose (ou que je cherche à soulever)
>> n'est pas de savoir si les langages orienté objet sont mieux ou moins
>> bien que ce qu'on faisait avant. On aura peut-être compris que, de mon
>> point de vue, ce qui relève de ce mode de programmation n'est pas <
>> furieusement très clair >. Cela étant je me doute bien que si c'est plus
>> compliqué c'est parce que cela permet sans doute de faire mieux dans
>> certains cas, même si ce sont des cas que je n'imagine peut-être pas, ou
>> que j'ai rencontrer sans en percevoir la véritable nature.
>
>
> En fait, je suis là des trolls lancés par des ignorants :
> 1. Les langages objets sont plus faciles à développer correctement que
> les autres parce qu'ils obligent le programmeur à se poser la question
> de la structure de donnée et de la portée des variables.

Je ne vois pas en quoi le procédural irait à l'encontre de cela. Le
problème du procédural (et sa force) est que c'est au programmeur de
savoir à qui appartient les données qu'une procédure manipule. En
objet, c'est facile, elles appartiennent à l'objet. Et
personnellement, j'ai vu beaucoup plus de programmes C++ objet et
Java mal fichus que de Fortran infect.

> 2. Python permet de faire du procédural même si c'est globalement
> déconseillé (il permet aussi de faire du lambda calcul)

J'ai toujours déconseillé l'utilisation de Python (ou alors
seulement avec des éditeurs qui changent automatiquement les groupes
d'espaces en tabulations).

Yliur

unread,
Nov 22, 2011, 11:10:08 PM11/22/11
to

Bonjour

Je précise que je ne connais pas bien Python, donc ce seront surtout
des réponses générales.

Le Tue, 22 Nov 2011 22:06:48 +0100
lionmarron <andre....@club-internet.fr> a écrit :

> Je ne suis pas sûr d'être forcément sur les bons forums : ma
> problématique (ma question autrement dit) pourrait être toutefois
> relative au langages de programmations en général, plus précisément
> aux langages de programmations actuels, et par conséquent aux
> langages orientés objet.
>
> Pour éviter de parler d'une façon abstraite, je précise que, dans le
> contexte, le langage que je tente d'utiliser est python (version 2.7).
>
> Ce que fait mon programme n'a en revanche pas d'importance : il
> s'agit avant tout de faire des essais et par conséquent c'est quelque
> chose de facile à faire. Lorsque je découvre un nouveau langage de
> programmation je programme toujours un jeu d'échecs, ce qui est donc
> le cas ici, toutefois il s'agira seulement de savoir si un
> déplacement est légal ou non, pas de juger de la valeur d'un coup. Il
> y a qq décennies je pouvais faire ça (et d'autres pouvaient faire
> plus) avec 32 K de ram.
>
> Étant donné qu'il faut malgré tout une certaine longueur de listing
> pour savoir si un coup est légal ou non,

Là je ne saisis pas bien... A vue de nez, 50-100 lignes ne suffisent pas
pour vérifier qu'un coup est valide ? Enfin ce n'est sans doute pas le
sujet important du message...


> je voudrais mettre ce qui
> fait ça dans une partie externe du programme, et c'est là que se
> trouve le fond du problème, ou en tout cas ce qui constitue le sujet
> de ce message.
>
> Peut-on faire une bibliothèque normale (quelque chose de normalement
> compréhensible pour un cerveau normal et pour un simple mortel), ou
> bien faut-il nécessairement faire une classe ?

Quand tu parles de "partie externe d'un programme", veux-tu réellement
faire une bibliothèque réutilisable ? Ou parles-tu simplement d'écrire
une partie du code du programme dans un autre fichier source en
Python ? Dans ce deuxième cas il faut simplement utiliser le mécanisme
de Python pour importer d'autres fichiers sources. A vue de nez, le
mécanisme des modules devrait faire ce que tu veux, mais je laisse ceux
qui s'y connaissent te conseiller si quelque chose est plus adapté.


> Ma principale référence est le livre de Swinnen <Apprendre à
> programmer avec Python> , édition 2005 (O'Reilly). D'après ce livre
> on pourrait penser qu'il n'y a pas d'autre moyens que de créer un
> classe, toutefois ce n'est pas dit explicitement, alors autant être
> sûr.

Autant que je sache, Python n'oblige pas à tout mettre dans des
classes. Il devrait y avoir moyen de faire autrement. Tous simplement
de la même manière que tu stockes de simples fonctions dans ton fichier
source principal, tu peux en stocker ailleurs et les importer.


> Je précise que la question que je pose (ou que je cherche à soulever)
> n'est pas de savoir si les langages orienté objet sont mieux ou moins
> bien que ce qu'on faisait avant. On aura peut-être compris que, de
> mon point de vue, ce qui relève de ce mode de programmation n'est pas
> < furieusement très clair >. Cela étant je me doute bien que si c'est
> plus compliqué c'est parce que cela permet sans doute de faire mieux
> dans certains cas, même si ce sont des cas que je n'imagine peut-être
> pas, ou que j'ai rencontrer sans en percevoir la véritable nature.

Ou que tu as résolu autrement, avec des habitudes différentes.

Les deux points que je trouve caractéristiques de la programmation par
objets, là, comme ça (et sans en dire de bien ou de mal, évitons que
les trolls nous tombent dessus) :
- Le fait de concevoir un programme autour des données plutôt
qu'autour de traitements. L'idée est de se concentrer sur les
structures de données et de concevoir le programme autour,
notamment en ajoutant à chaque classe des fonctions (méthodes) pour
agir sur ses données, le but étant d'éviter que la représentation
interne des données n'apparaisse au reste du programme. Objectif :
réduire le code source concerné par la manipulation de ces données,
pour éviter qu'une modification dans cette représentation n'impacte
tout le programme.
La conception objet se construit donc plus en découpant le monde en
objets et moins en faisant du découpage en traitements, redécoupés
en sous-traitements.
- L'organisation des données en hiérarchies, ce qui constitue un
mécanisme d'extension des classes mais surtout permet le
polymorphisme. Le fait d'avoir une liste d'objets pas tous de la
même classe mais ayant un ancêtre commun garantit qu'ils
implémentent tous les méthodes de cet ancêtre, éventuellement de
manière différente, et permet de traiter tous ces objets
uniformément depuis l'extérieur tout en leur laissant adapter le
comportement qui leur est demandé (donc l'implémentation de la
méthode) à leur nature réelle. En plus simple : demander à
différentes objets de réaliser une opération, à chacun de la
réaliser selon sa classe réelle.



> Si certains acceptent de me promettre qu'ils ne le répéteront pas, je
> veux bien leur concéder que je n'y crois pas réellement, autrement
> dit je pense que c'est de la blague. Mais ça je l'ai pas dit, je l'ai
> seulement pensé. (Autrement dit si certains ont pu lire ce qui
> précède cela signifie qu'ils se trompent : ils ont cru le lire.)

"De la blague" n'est pas une appréciation très utile pour comprendre et
peser les avantages et les inconvénients. Et tu peux bien en penser ce
que tu veux, mais donner un avis juste après avoir dit que ce n'est pas
très clair pour toi, c'est un peu étrange :) .


> A vos claviers. Et que ça saute. Ça manque d'agitation ici (c'est pas
> possible).
>
> Suivi sur fr.comp.algorithmes

Là je ne comprends pas très bien... si ton but est juste de savoir
comment faire pour découper ton programme Python en morceaux, c'est une
question très spécifique à Python à mon avis.

Je ne positionne pas le suivi, que tu as simplement annoncé.

Pierre Maurette

unread,
Nov 23, 2011, 2:12:39 AM11/23/11
to
lionmarron :

[pffffft]

Python est un langage peu verbeux. Vous, en revanche...
En Python, on peut aussi bien ignorer l'OO que le systématiser, les
deux attitudes étant à mon avis excessives. Ici, le problème est de
toute évidence naturellement OO.

--
Pierre Maurette


lionmarron

unread,
Nov 23, 2011, 4:13:26 AM11/23/11
to
Le 23/11/2011 05:10, Yliur a écrit :
>>
>> Étant donné qu'il faut malgré tout une certaine longueur de listing
>> pour savoir si un coup est légal ou non,
>
> Là je ne saisis pas bien... A vue de nez, 50-100 lignes ne suffisent pas
> pour vérifier qu'un coup est valide ?
Non, pas pour avoir une ou deux listes des coups autorisés tout au moins
(en partant soit de la case de départ, soit de la case d'arrivée).

>> Peut-on faire une bibliothèque normale (quelque chose de normalement
>> compréhensible pour un cerveau normal et pour un simple mortel), ou
>> bien faut-il nécessairement faire une classe ?
>
> Quand tu parles de "partie externe d'un programme", veux-tu réellement
> faire une bibliothèque réutilisable ?
Oui ça serait l'idée, mais je me contenterais de quelque chose
d'utilisable même seulement en Python.

> Ou parles-tu simplement d'écrire
> une partie du code du programme dans un autre fichier source en
> Python ? Dans ce deuxième cas il faut simplement utiliser le mécanisme
> de Python pour importer d'autres fichiers sources.
Il me faudra peut-être chercher de ce côté alors.

> A vue de nez, le
> mécanisme des modules devrait faire ce que tu veux, mais je laisse ceux
> qui s'y connaissent te conseiller si quelque chose est plus adapté.
>
>
>> Ma principale référence est le livre de Swinnen<Apprendre à
>> programmer avec Python> , édition 2005 (O'Reilly). D'après ce livre
>> on pourrait penser qu'il n'y a pas d'autre moyens que de créer un
>> classe, toutefois ce n'est pas dit explicitement, alors autant être
>> sûr.
>
> Autant que je sache, Python n'oblige pas à tout mettre dans des
> classes. Il devrait y avoir moyen de faire autrement. Tous simplement
> de la même manière que tu stockes de simples fonctions dans ton fichier
> source principal, tu peux en stocker ailleurs et les importer.
Ben je sais pas trop.

>> Si certains acceptent de me promettre qu'ils ne le répéteront pas, je
>> veux bien leur concéder que je n'y crois pas réellement, autrement
>> dit je pense que c'est de la blague. Mais ça je l'ai pas dit, je l'ai
>> seulement pensé. (Autrement dit si certains ont pu lire ce qui
>> précède cela signifie qu'ils se trompent : ils ont cru le lire.)
>
> "De la blague" n'est pas une appréciation très utile pour comprendre et
> peser les avantages et les inconvénients.
Effectivement. Disons que ce qu'il s'agissait de critiquer est plutôt la
fait d'enseigner comment faire une classe (et encore dans un type de
contexte qui n'est peut-être le plus facile à comprendre) sans expliquer
comment procéder plus simplement lorsque la situation s'y prête. (Le
livre de Swinnen ne l'explique pas, et, sur ce plan là, je ne crois pas
qu'il soit différent de ce qu'on trouve en général aujourd'hui en
matière d'ouvrages d'initiation à un langage).

>> Suivi sur fr.comp.algorithmes
>
> Là je ne comprends pas très bien... si ton but est juste de savoir
> comment faire pour découper ton programme Python en morceaux, c'est une
> question très spécifique à Python à mon avis.
Ce sera peut-être dans un second temps alors.

>
> Je ne positionne pas le suivi, que tu as simplement annoncé.
Le fait est que j'ignore comment on positionne un suivit (je croyais
qu'on se contentait de dire où le suivi était sensé se faire).

Et merci pour ces réponses bien sûr.

--
lionmarron



yves

unread,
Nov 23, 2011, 8:54:03 AM11/23/11
to
Le Tue, 22 Nov 2011 22:06:48 +0100, lionmarron a écrit:

Bonjour,

> Si certains acceptent de me promettre qu'ils ne le répéteront pas, je
> veux bien leur concéder que je n'y crois pas réellement, autrement dit
> je pense que c'est de la blague. Mais ça je l'ai pas dit, je l'ai
> seulement pensé. (Autrement dit si certains ont pu lire ce qui précède
> cela signifie qu'ils se trompent : ils ont cru le lire.)

je ne suis pas sûr d'avoir compris l'interrogation (je réponds donc peut-
être à côté de la plaque), mais si tu lis l'anglais, essaye de lire ce
texte (sur l'OO en python), que je trouve particulièrement clair:

http://www.alan-g.me.uk/tutor/index.htm

ou celui-là pour python 3:

http://www.alan-g.me.uk/l2p/tutclass.htm

Cordialement,
--
Yves

yves

unread,
Nov 23, 2011, 8:55:39 AM11/23/11
to
Le Wed, 23 Nov 2011 13:54:03 +0000, yves a écrit:

> http://www.alan-g.me.uk/tutor/index.htm

Pardon, celui-là, plutôt:

http://www.alan-g.me.uk/tutor/tutclass.htm


--
Yves

lionmarron

unread,
Nov 23, 2011, 1:04:11 PM11/23/11
to
Le 23/11/2011 14:54, yves a écrit :
> Le Tue, 22 Nov 2011 22:06:48 +0100, lionmarron a écrit:
>
> Bonjour,
>
>> Si certains acceptent de me promettre qu'ils ne le répéteront pas, je
>> veux bien leur concéder que je n'y crois pas réellement, autrement dit
>> je pense que c'est de la blague. Mais ça je l'ai pas dit, je l'ai
>> seulement pensé. (Autrement dit si certains ont pu lire ce qui précède
>> cela signifie qu'ils se trompent : ils ont cru le lire.)
>
> je ne suis pas sûr d'avoir compris l'interrogation (je réponds donc peut-
> être à côté de la plaque), mais si tu lis l'anglais,
Non hélas.

essaye de lire ce
> texte (sur l'OO en python), que je trouve particulièrement clair:
>
> http://www.alan-g.me.uk/tutor/index.htm
De plus, pour des raisons que j'ignore, la fonction traduire en français
de Google Chromium ne marche pas avec ce site.

--
lionmarron



lionmarron

unread,
Nov 23, 2011, 1:13:16 PM11/23/11
to
Le 22/11/2011 22:21, JKB a écrit :
> Le Tue, 22 Nov 2011 22:06:48 +0100,
> lionmarron<andre....@club-internet.fr> écrivait :

>> Je précise que la question que je pose (ou que je cherche à soulever)
>> n'est pas de savoir si les langages orienté objet sont mieux ou moins
>> bien que ce qu'on faisait avant. On aura peut-être compris que, de mon
>> point de vue, ce qui relève de ce mode de programmation n'est pas<
>> furieusement très clair>.s
>
> Ce n'est pas le but. Le but est d'encapsuler des données dans des
> objets pour éviter au maximum que le programmateur de base touche à
> ce qui peut fâcher comme les allocations explicites de mémoire. La
> contrepartie est que c'est lourd et assez souvent write-only
Ça veut dire qu'on peut seulement écrire mais pas lire ? Je suis pas sûr
de comprendre.

> lorsque
> ce n'est pas documenté correctement. Passer sur un code C++ complexe
> non documenté est une gageure, mais je m'égare.

>> A vos claviers. Et que ça saute. Ça manque d'agitation ici (c'est pas
>> possible).
>
> Je crois que j'ai marché dedans...
Mais non c'était pour rire.

--
lionmarron



lionmarron

unread,
Nov 23, 2011, 1:23:23 PM11/23/11
to
Le 23/11/2011 08:12, Pierre Maurette a écrit :
> lionmarron :
>
> [pffffft]
>
> Python est un langage peu verbeux.
Oui mais je ne suis pas sûr que les erreurs y soient plus faciles à
corriger que dans un autre langage. Donc cela risque de devenir plutôt
verbeux dés que quelque chose ne marche pas comme prévu.

> Vous, en revanche...
> En Python, on peut aussi bien ignorer l'OO que le systématiser, les deux
> attitudes étant à mon avis excessives. Ici, le problème est de toute
> évidence naturellement OO.
Si tel est le cas j'ignore pourquoi. Toutefois comme je n'ai pas trouvé
d'exemples qui me permettrait de voir comment faire autrement, a priori
je vais résoudre le problème en créant une classe. Ensuite je pourrai
toujours aller voir sur un forum Python pour essayer de savoir si on
peut procéder plus simplement ou non (et le cas échéant pourquoi).

--
lionmarron



JKB

unread,
Nov 23, 2011, 3:44:20 PM11/23/11
to
Le Wed, 23 Nov 2011 19:13:16 +0100,
lionmarron <andre....@club-internet.fr> écrivait :
> Le 22/11/2011 22:21, JKB a écrit :
>> Le Tue, 22 Nov 2011 22:06:48 +0100,
>> lionmarron<andre....@club-internet.fr> écrivait :
>
>>> Je précise que la question que je pose (ou que je cherche à soulever)
>>> n'est pas de savoir si les langages orienté objet sont mieux ou moins
>>> bien que ce qu'on faisait avant. On aura peut-être compris que, de mon
>>> point de vue, ce qui relève de ce mode de programmation n'est pas<
>>> furieusement très clair>.s
>>
>> Ce n'est pas le but. Le but est d'encapsuler des données dans des
>> objets pour éviter au maximum que le programmateur de base touche à
>> ce qui peut fâcher comme les allocations explicites de mémoire. La
>> contrepartie est que c'est lourd et assez souvent write-only
> Ça veut dire qu'on peut seulement écrire mais pas lire ? Je suis pas sûr
> de comprendre.

Ça veut dire exactement ça. Un code objet peut rapidement n'être
lisible que par celui qui l'a écrit. On appelle ça la protection de
de l'emploi. Un code procédural peut être absolument ignoble, mais
est beaucoup plus facilement compréhensible (et aussi plus difficile
à débugguer, c'est l'envers de la médaille). Typiquement en C++, dès
qu'on fait des choses subtiles, on ne sait plus vraiment qui fait
quoi. Que celui qui n'a jamais eu de problème avec une fonction
virtuelle qui ne fait pas ce qu'on croit parce que ce n'est pas la
bonne qui est appelée me jette la première pierre !

Yliur

unread,
Nov 24, 2011, 2:39:06 AM11/24/11
to
Le Wed, 23 Nov 2011 10:13:26 +0100
lionmarron <andre....@club-internet.fr> a écrit :

> Le 23/11/2011 05:10, Yliur a écrit :
> >>
> >> Étant donné qu'il faut malgré tout une certaine longueur de listing
> >> pour savoir si un coup est légal ou non,
> >
> > Là je ne saisis pas bien... A vue de nez, 50-100 lignes ne
> > suffisent pas pour vérifier qu'un coup est valide ?
> Non, pas pour avoir une ou deux listes des coups autorisés tout au
> moins (en partant soit de la case de départ, soit de la case
> d'arrivée).

Par curiosité : que contient cette liste ? Là, naïvement, si je devais
le faire, je vois 6 types de pièces avec une pincée de mouvements
chacun, dans des boucles pour ceux qui peuvent les prolonger en
vérifiant qu'il n'y a pas d'obstacle.

Pour les modules en Python, sauf si j'ai manqué quelque chose, ça peut
être quelque chose d'aussi simple qu'écrire un fichier coups.py dans
le même répertoire (tant qu'il n'y a pas beaucoup de modules ça ira) et
l'importer dans un autre en écrivant "import coups" ou "import * from
coups" (ce qui permet d'éviter d'écrire coups.fonction1, coups.f2 et
juste le nom de la fonction apparemment, mais à vérifier).

<http://python.developpez.com/faq> a l'air intéressant.


> > Je ne positionne pas le suivi, que tu as simplement annoncé.
> Le fait est que j'ignore comment on positionne un suivit (je croyais
> qu'on se contentait de dire où le suivi était sensé se faire).

Là où tu as choisi les différents groupes, tu ajoutes une troisième
ligne contenant le nom du groupe dans lequel tu positionnes le suivi.
Et devant le nom du groupe, tu sélectionnes l'en-tête que tu veux
choisir : je ne me souviens pas des noms dans Thunderbird, mais ça doit
être une liste déroulante dans laquelle tu choisis quelque chose comme
"Suivi sur" plutôt que "Groupe de discussion" (l'en-tête qui apparaît
devant les deux autres lignes).

L'annoncer dans le texte c'est en plus, parce que les humains ne font
pas toujours attention aux en-têtes.

Laurent Claessens

unread,
Nov 24, 2011, 2:54:47 AM11/24/11
to

> Par curiosité : que contient cette liste ? Là, naïvement, si je devais
> le faire, je vois 6 types de pièces avec une pincée de mouvements
> chacun, dans des boucles pour ceux qui peuvent les prolonger en
> vérifiant qu'il n'y a pas d'obstacle.

Sans être le moins du monde expert aux échecs, à mon avis les échecs
sont plus complexes que ça. Par exemple il faut vérifier si le coup ne
provoque pas un échec au roi. De plus en cas de roque (ça fait deux
coups très spéciaux à traiter), il faut vérifier si le roi ne passe pas
sous l'échec.
Les pions ne peuvent avancer qu'en ligne droite, mais prendre une pièce
adverse qu'en biais, ...

Au premier mouvement, les pions peuvent faire deux cases (et il faut
vérifier encore qu'il n'y a pas échec ou roi dans la position
intermédiaire, je crois)

Puis y'a des règles spéciales concernant le fait de rejouer un coup qui
a déjà été joué.

J'en oublie surement. M'est avis que tout bien faire ne tient pas en 50
lignes ...

... surtout si on met des docstring très verbeux :d


Bonne journée
Laurent

Francois Lafont

unread,
Nov 24, 2011, 3:33:32 AM11/24/11
to
Le 24/11/2011 08:54, Laurent Claessens a écrit :

> Sans être le moins du monde expert aux échecs, à mon avis les échecs
> sont plus complexes que ça. Par exemple il faut vérifier si le coup ne
> provoque pas un échec au roi. De plus en cas de roque (ça fait deux
> coups très spéciaux à traiter), il faut vérifier si le roi ne passe pas
> sous l'échec.

Il faut aussi que le roi ne soit pas en échec au moment du roque (juste
avant) et que le roi et la tour concernée n'aient jamais bougé.

> Les pions ne peuvent avancer qu'en ligne droite, mais prendre une pièce
> adverse qu'en biais, ...

Et il y a la promotion du pion aussi : en une dame, un cavalier, un fou,
une tour. Et la prise en passant aussi. seulement valable lorsque le
pion d'à côté vient juste d'avancer de deux cases.

> Au premier mouvement, les pions peuvent faire deux cases (et il faut
> vérifier encore qu'il n'y a pas échec ou roi dans la position
> intermédiaire, je crois)

Après le coup du pion (ou de n'importe quelle pièce) des blancs (resp
des noirs) le roi blanc (resp noir) ne doit pas être en situation d'échec.

> Puis y'a des règles spéciales concernant le fait de rejouer un coup qui
> a déjà été joué.

Pas sûr, mais je crois que si on a 3 trois fois de suite la même
position, la partie est nulle.

> J'en oublie surement. M'est avis que tout bien faire ne tient pas en 50
> lignes ...

Clairement.

--
François Lafont

lionmarron

unread,
Nov 24, 2011, 11:33:07 AM11/24/11
to
Le 24/11/2011 08:39, Yliur a écrit :
> Le Wed, 23 Nov 2011 10:13:26 +0100
> lionmarron<andre....@club-internet.fr> a écrit :
>
>> Le 23/11/2011 05:10, Yliur a écrit :
>>>>
>>>> Étant donné qu'il faut malgré tout une certaine longueur de listing
>>>> pour savoir si un coup est légal ou non,
>>>
>>> Là je ne saisis pas bien... A vue de nez, 50-100 lignes ne
>>> suffisent pas pour vérifier qu'un coup est valide ?
>> Non, pas pour avoir une ou deux listes des coups autorisés tout au
>> moins (en partant soit de la case de départ, soit de la case
>> d'arrivée).
>
> Par curiosité : que contient cette liste ?
Prenons la liste qui commence avec les cases de départ. Le langage
Python étant tout ce qu'on veut sauf clair, je vais faire comme si nous
étions dans un langage normal éventuellement pas structuré, et parler de
tableau à 2 dimensions. Disons qu'on met le tableau sur une feuille de
papier et la feuille de papier sur un panneau vertical.

Dans une dimension, disons la hauteur, et à gauche de chaque rangée (il
s'agit donc d'une colonne), je mets le numéro des cases de départ, par
exemple de 22 à 99 (il y a d'autres choix possibles), puis un numéro qui
servira de fin de liste (donc un numéro non autorisé pour une case). Il
y a au maximum 16 figures, donc pour cette dimension il faut 17 places.

Dans l'autre dimension, disons la largeur, et de gauche à droite en
partant de la case de départ, je mets le numéro des cases d'arrivée
autorisées, puis un numéro de fin de liste. Il y a au maximum 27 cases
d'arrivées pour une case de départ, donc pour cette dimension il faut 29
places (la case de départ, les cases d'arrivées puis le numéro <fin de
liste>).

> Là, naïvement, si je devais
> le faire, je vois 6 types de pièces avec une pincée de mouvements
> chacun, dans des boucles pour ceux qui peuvent les prolonger en
> vérifiant qu'il n'y a pas d'obstacle.
Comme permettent d'en juger les messages de Laurent et François c'est
peut-être ce qu'on appelle de l'humour involontaire.

> Pour les modules en Python, sauf si j'ai manqué quelque chose, ça peut
> être quelque chose d'aussi simple qu'écrire un fichier coups.py dans
> le même répertoire (tant qu'il n'y a pas beaucoup de modules ça ira) et
> l'importer dans un autre en écrivant "import coups" ou "import * from
> coups" (ce qui permet d'éviter d'écrire coups.fonction1, coups.f2 et
> juste le nom de la fonction apparemment, mais à vérifier).
Je suis pas sûr d'avoir compris : le fait est que je ne sais pas ce
qu'est un module.

> <http://python.developpez.com/faq> a l'air intéressant.
J'ai programmé en Python en 2009 je crois, puis un peu au début 2011,
mais pas entre temps, donc mes souvenirs ne sont pas forcément très
précis, toutefois je me souviens d'avoir imprimé cette FAQ et d'y avoir
remarqué des choses intéressantes. (Mais je ne crois pas qu'elle parle
de module par exemple.)

> Là où tu as choisi les différents groupes, tu ajoutes une troisième
> ligne contenant le nom du groupe dans lequel tu positionnes le suivi.
> Et devant le nom du groupe, tu sélectionnes l'en-tête que tu veux
> choisir : je ne me souviens pas des noms dans Thunderbird, mais ça doit
> être une liste déroulante dans laquelle tu choisis quelque chose comme
> "Suivi sur" plutôt que "Groupe de discussion" (l'en-tête qui apparaît
> devant les deux autres lignes).
Cette fois j'aurai essayé.

>
> L'annoncer dans le texte c'est en plus, parce que les humains ne font
> pas toujours attention aux en-têtes.


--
lionmarron



Yliur

unread,
Nov 24, 2011, 2:22:44 PM11/24/11
to
Le Thu, 24 Nov 2011 17:33:07 +0100
D'accord.

> > Là, naïvement, si je devais
> > le faire, je vois 6 types de pièces avec une pincée de mouvements
> > chacun, dans des boucles pour ceux qui peuvent les prolonger en
> > vérifiant qu'il n'y a pas d'obstacle.
> Comme permettent d'en juger les messages de Laurent et François c'est
> peut-être ce qu'on appelle de l'humour involontaire.
>
> > Pour les modules en Python, sauf si j'ai manqué quelque chose, ça
> > peut être quelque chose d'aussi simple qu'écrire un fichier
> > coups.py dans le même répertoire (tant qu'il n'y a pas beaucoup de
> > modules ça ira) et l'importer dans un autre en écrivant "import
> > coups" ou "import * from coups" (ce qui permet d'éviter d'écrire
> > coups.fonction1, coups.f2 et juste le nom de la fonction
> > apparemment, mais à vérifier).
> Je suis pas sûr d'avoir compris : le fait est que je ne sais pas ce
> qu'est un module.

Un tas de truc programmés.

Une manière de rassembler des fonctions, classes, constantes, ... et de
pouvoir les importer dans une autre partie de programme.

Un moyen de découper un programme en plusieurs morceaux.

Si j'ai bien compris, en Python tu découpes ton programmes en fichier,
qui constituent automatiquement des "modules". Donc tu peux répartir
ton code source dans plusieurs fichier truc.py machin.py et chose.py et
si dans truc.py tu veux accéder aux fonctions définies dans chose .py
tu écris "import chose" ou "import * from chose". C'est ce que tu
cherches, non ? Définir des fonctions dans un fichier séparé de celui
de ton programme principal ?

> > <http://python.developpez.com/faq> a l'air intéressant.
> J'ai programmé en Python en 2009 je crois, puis un peu au début 2011,
> mais pas entre temps, donc mes souvenirs ne sont pas forcément très
> précis, toutefois je me souviens d'avoir imprimé cette FAQ et d'y
> avoir remarqué des choses intéressantes. (Mais je ne crois pas
> qu'elle parle de module par exemple.)

Si, il y a au moins quelques remarques sur les modules dans la partie
Généralités..

> > Là où tu as choisi les différents groupes, tu ajoutes une troisième
> > ligne contenant le nom du groupe dans lequel tu positionnes le
> > suivi. Et devant le nom du groupe, tu sélectionnes l'en-tête que tu
> > veux choisir : je ne me souviens pas des noms dans Thunderbird,
> > mais ça doit être une liste déroulante dans laquelle tu choisis
> > quelque chose comme "Suivi sur" plutôt que "Groupe de
> > discussion" (l'en-tête qui apparaît devant les deux autres lignes).
> Cette fois j'aurai essayé.

Réussi :) .

Même si je pense que tu aurais plus de chance de l'autre côté. Enfin à
moins qu'ils n'aient répondu que dans leur groupe, on n'a pas trop vu
passer leurs messages non plus.

yves

unread,
Nov 24, 2011, 2:34:33 PM11/24/11
to
Le Thu, 24 Nov 2011 17:33:07 +0100, lionmarron a écrit:

Bonjour,

> le fait est que je ne sais pas ce qu'est un module.

Si on nomme ça une bibliothèque, c'est plus parlant?

@+
--
Yves

yves

unread,
Nov 24, 2011, 2:47:06 PM11/24/11
to
Le Thu, 24 Nov 2011 17:33:07 +0100, lionmarron a écrit:


> Je suis pas sûr d'avoir compris : le fait est que je ne sais pas ce
> qu'est un module.

C'est quand même vraiment le B.A.BA. Vous n'avez personne sous la main
pour vous aider à faire les premiers pas en python?


@+
--
Yves

lionmarron

unread,
Nov 24, 2011, 4:08:09 PM11/24/11
to
Non, Compte tenu de mon état de santé j'ai une aide à domicile et ma
mère vient me voir presque une fois par semaine, mais je suis sûr
qu'aucune des deux ne programme en Python.

Cela dit reconnaissons qu'il n'est pas nécessaire d'en savoir très long
pour en savoir plus que moi. J'ai utilisé des bibliothèques fournies
avec les langages, un peu en Pascal puis un peu en Delphi, mais je n'ai
pas utilisé ces langages suffisamment longtemps pour programmer ne
serait-ce qu'un seul module.

Enfin sauf en Latex (ou il y a qq chose de semblable), mais, sans jouer
sans jouer sur les mots, ce n'est pas exactement un langage de
programmation (tout au moins pas dans le sens où Python est un langage
de programmation).

>
> @+


--
lionmarron



yves

unread,
Nov 24, 2011, 5:59:59 PM11/24/11
to
Le Thu, 24 Nov 2011 22:08:09 +0100, lionmarron a écrit:


> Non, Compte tenu de mon état de santé j'ai une aide à domicile et ma
> mère vient me voir presque une fois par semaine, mais je suis sûr
> qu'aucune des deux ne programme en Python.

Ok. C'est vrai que dans la vraie vie, c'est plutôt rare, les gens qui
programment en Python (peut-être un dans un LUG, s'il en existe un pas
trop loin).

> Cela dit reconnaissons qu'il n'est pas nécessaire d'en savoir très long
> pour en savoir plus que moi. J'ai utilisé des bibliothèques fournies
> avec les langages, un peu en Pascal puis un peu en Delphi, mais je n'ai
> pas utilisé ces langages suffisamment longtemps pour programmer ne
> serait-ce qu'un seul module.


Il ne faut pas se faire une montagne du concept de module ou
bibliothèque. Voici un exemple en quelques lignes de Python, adapté
d'Alan Gauld:

*****


Copier la fonction ci-dessous dans un éditeur de texte et sauver le
fichier sous le nom tabledemultiplication.py.

def imprime_table(multiplicateur):
print "--- Impression de la table de %d ---" % multiplicateur
for n in range(1,10):
print "%d x %d = %d" % (n, multiplicateur, n*multiplicateur)

#maintenant au prompt python, taper

>>> import tabledemultiplication
>>> tabledemultiplication.imprime_table(7)

Donc voilà ce qu'est un module en Python, et comment on l'utilise.

Evidemment, il n'y a qu'une fonction dans ce module, mais c'est facile
d'en ajouter d'autres.

Bon, je positionne le suivi de ce message sur fr.comp.lang.python

@+
--
Yves

Julien

unread,
Nov 24, 2011, 6:26:19 PM11/24/11
to
Sans être un expert en génie logiciel, je pense qu'il ne faut pas
faire qu'une analyse technique ou de conception. La programmation-
objet permet de spécifier les métiers, bâtir des méthodes, il permet
une forme de standardisation et d'industrialisation du logiciel et
donc permet le changement des hommes de manière flexible, réduire les
coûts, optimiser les flux, permettre des indicateurs de performance
bref tout ce qui est cher à notre économie en pleine santé :). Les
informaticiens qui ont exercé dans la sidérurgie ou l'automobile
peuvent constater des similarités entre le secteur de la production et
le développement logiciel. Cela permet enfin de changer un développeur
à 1200 euros par un autre à 600 euros en Inde sans angoisse que celui-
ci ne parte avec le savoir-faire.

J.H

JKB

unread,
Nov 25, 2011, 2:30:31 PM11/25/11
to
[En-tête "Followup-To:" positionné à fr.comp.algorithmes.]
Le Thu, 24 Nov 2011 15:26:19 -0800 (PST),
Julien <fin...@gmail.com> écrivait :
Ça, je l'encadre. Personnellement, je fais des piges à droite et à
gauche dans des langages aussi tordu que Fortran, C, C++ et d'autres
comme Cobol. Il est très simple de modifier un programme impératif
ou procédural. Lorsqu'on n'a pas conçu soi-même un truc objet, il
est extrèmement compliqué d'en saisir toutes les subtilités. Par
subtilités, je n'entends pas ce qui se passe au niveau d'une classe,
mais au niveau du programme tout entier. La plupart du temps, dès
qu'on a des modifications un peu sévères à faire dans un code C++,
on repart à zéro car on perd moins de temps.

Bertrand Lenoir-Welter

unread,
Nov 26, 2011, 5:23:33 AM11/26/11
to
>> Sans être un expert en génie logiciel, je pense qu'il ne faut pas
>> faire qu'une analyse technique ou de conception. La programmation-
>> objet permet de spécifier les métiers, bâtir des méthodes, il permet
>> une forme de standardisation et d'industrialisation du logiciel et
>> donc permet le changement des hommes de manière flexible, réduire les
>> coûts, optimiser les flux, permettre des indicateurs de performance
>> bref tout ce qui est cher à notre économie en pleine santé :). Les
>> informaticiens qui ont exercé dans la sidérurgie ou l'automobile
>> peuvent constater des similarités entre le secteur de la production et
>> le développement logiciel. Cela permet enfin de changer un développeur
>> à 1200 euros par un autre à 600 euros en Inde sans angoisse que celui-
>> ci ne parte avec le savoir-faire.
>
> Ça, je l'encadre. Personnellement, je fais des piges à droite et à
> gauche dans des langages aussi tordu que Fortran, C, C++ et d'autres
> comme Cobol. Il est très simple de modifier un programme impératif
> ou procédural. Lorsqu'on n'a pas conçu soi-même un truc objet, il
> est extrèmement compliqué d'en saisir toutes les subtilités. Par
> subtilités, je n'entends pas ce qui se passe au niveau d'une classe,
> mais au niveau du programme tout entier. La plupart du temps, dès
> qu'on a des modifications un peu sévères à faire dans un code C++,
> on repart à zéro car on perd moins de temps.


Les deux points de vue me semblent tout aussi caricaturaux. A mon avis,
les programmes sont plus faciles à maintenir lorsqu'ils ont été bien
conçus au départ et qu'on n'a pas ensuite rajouté des modifs à l'arrache
au fil du temps, à grands renforts de variables globales. On peut faire
de l'objet véritablement dégueux (j'en ai fait et j'en suis pas fier)
ainsi que du procédural super-propre, tout dépend du sens de
l'organisation du concepteur et de ceux qui auront à intervenir par la
suite. Ça dépend aussi de la clarté des demandes du client, qui n'est
pas forcément au rendez-vous. Anticiper les possibles évolutions n'est
pas toujours une sinécure, mais il faut s'y coller. Rien ne remplace
l'expérience. Qui n'a jamais éprouvé un profond sentiment de
découragement face à un code lardé de greffons réalisés dans l'urgence
et oubliés ensuite ?

De toute façon, in fine, c'est du procédural.

JKB

unread,
Nov 26, 2011, 6:52:27 AM11/26/11
to
Le Sat, 26 Nov 2011 11:23:33 +0100,
Bertrand Lenoir-Welter <bertrand-dot-2011@galaad-dot-net> écrivait :
Non, in fine, c'est de l'impératif, mais on digresse. Mon propos
n'est pas de savoir si le procédural est supérieur ou non à l'objet.
Mon propos est juste de dire qu'il est plus facile de voir les
enchaînements logiques dans le détail dans un code procédural qu'on
n'a pas écrit que dans un code objet qu'on n'a pas conçu. Lorsqu'on
arrive sur un programme qu'on doit maintenir et qu'on n'a pas écrit,
ça fait une grosse différence. Personnellement, j'hésite toujours à
accepter un boulot consistant à rajouter des fonctions dans un gros
code objet, on ne sait jamais sur quoi on va tomber (même lorsque le
code est a priori propre).

Que l'on voit très rapidement avec un schéma UML ce qui se passe
dans un code C++, c'est un fait. Que l'on soit capable inteligemment
de rajouter quelque chose dans le même programme est beaucoup plus
dur parce qu'il est dans les faits très compliqué de voir qui fait
quoi (mécanisme d'héritage, fonctions virtuelles, polymorphisme,
toussa...).

Wykaaa

unread,
Dec 1, 2011, 2:21:35 PM12/1/11
to
JKB a écrit :
> Le Sat, 26 Nov 2011 11:23:33 +0100,
> Bertrand Lenoir-Welter <bertrand-dot-2011@galaad-dot-net> écrivait :
>>>> Sans être un expert en génie logiciel, je pense qu'il ne faut pas
>>>> faire qu'une analyse technique ou de conception. La programmation-
>>>> objet permet de spécifier les métiers, bâtir des méthodes, il permet
>>>> une forme de standardisation et d'industrialisation du logiciel et
>>>> donc permet le changement des hommes de manière flexible, réduire les
>>>> coûts, optimiser les flux, permettre des indicateurs de performance
>>>> bref tout ce qui est cher à notre économie en pleine santé :). Les
>>>> informaticiens qui ont exercé dans la sidérurgie ou l'automobile
>>>> peuvent constater des similarités entre le secteur de la production et
>>>> le développement logiciel. Cela permet enfin de changer un développeur
>>>> à 1200 euros par un autre à 600 euros en Inde sans angoisse que celui-
>>>> ci ne parte avec le savoir-faire.
>>> Ça, je l'encadre. Personnellement, je fais des piges à droite et à
>>> gauche dans des langages aussi tordu que Fortran, C, C++ et d'autres
>>> comme Cobol. Il est très simple de modifier un programme impératif
>>> ou procédural. Lorsqu'on n'a pas conçu soi-même un truc objet, il
>>> est extrèmement compliqué d'en saisir toutes les subtilités. Par
>>> subtilités, je n'entends pas ce qui se passe au niveau d'une classe,
>>> mais au niveau du programme tout entier. La plupart du temps, dès
>>> qu'on a des modifications un peu sévères à faire dans un code C++,
>>> on repart à zéro car on perd moins de temps.

Ceci est absolument faux. Si l'on doit repartir à zéro, c'est justement
parce que la conception et/ou la programmation ont été faites par des
personnes qui ne maîtrisaient pas l'approche objet, ni le langage C++.
J'ai (plus que) trempé dans de gros projets objets (C++ et Java
principalement) de plus de 3 millions de lignes de code. Les programmes
en question doivent avoir une durée de vie de 30 à 35 ans au moins
(c'est dans le cahier des charges). Bien sûr, pendant toutes ces années,
ils évoluent. On ne recommence pas à zéro même si les modifications sont
majeures.

J'ai aussi l'expérience du procédural et de l'impératif. Je peux vous
dire qu'entre faire des modifications dans du code volumineux (je parle
toujours de plusieurs millions de lignes) procédural où il y a des
milliers de variables globales et du code objet bien fichu (très grande
modularité avec des dizaines de milliers de classes, comme j'en ai vu,
utilisation judicieuse du polymorphisme, etc.), je choisis sans hésiter
le code objet. C'est beaucoup plus facile.

>> Les deux points de vue me semblent tout aussi caricaturaux. A mon avis,
>> les programmes sont plus faciles à maintenir lorsqu'ils ont été bien
>> conçus au départ et qu'on n'a pas ensuite rajouté des modifs à l'arrache
>> au fil du temps, à grands renforts de variables globales. On peut faire
>> de l'objet véritablement dégueux (j'en ai fait et j'en suis pas fier)
>> ainsi que du procédural super-propre, tout dépend du sens de
>> l'organisation du concepteur et de ceux qui auront à intervenir par la
>> suite. Ça dépend aussi de la clarté des demandes du client, qui n'est
>> pas forcément au rendez-vous. Anticiper les possibles évolutions n'est
>> pas toujours une sinécure, mais il faut s'y coller. Rien ne remplace
>> l'expérience. Qui n'a jamais éprouvé un profond sentiment de
>> découragement face à un code lardé de greffons réalisés dans l'urgence
>> et oubliés ensuite ?

Voilà. Du code "réalisé dans l'urgence", c'est ça le problème, que le
code soit objet, procédural, impératif ou fonctionnel. Hélas, dans la
réalité, le code est presque toujours écrit ou modifié dans l'urgence
car c'est la gestion de projet qui est en cause, surtout en France où il
n'y a aucune culture sur ce sujet : on va pratiquement toujours au
"moins disant". C'est ce qui coûte le plus cher car ensuite il faut
refaire...

>> De toute façon, in fine, c'est du procédural.

???

>
> Non, in fine, c'est de l'impératif, mais on digresse. Mon propos
> n'est pas de savoir si le procédural est supérieur ou non à l'objet.
> Mon propos est juste de dire qu'il est plus facile de voir les
> enchaînements logiques dans le détail dans un code procédural qu'on
> n'a pas écrit que dans un code objet qu'on n'a pas conçu.

Il est vrai que le code objet est plus "atomisé", justement parce qu'il
est censé être plus modulaire (au sens objet du terme : faible couplage
entre classes ou modules et forte cohésion interne de chaque classe ou
module. Une classe est censée représenter et implémenter une et une
seule "abstraction" au sens de Grady Booch).
Cependant si l'on respecte les principes de l'approche objet :
abstraction, encapsulation, modularité (faible couplage, forte cohésion)
et hiérarchie (agrégation, composition et héritage) alors la maintenance
d'un code objet est extrêmement plus facile que celle d'un code
impératif qui se présente bien souvent comme un vrai plat de spaghettis.
Dire que "il est plus facile de voir les enchaînements logiques dans le
détail dans un code procédural" me fait penser aux programmeurs en
assembleur qui reprochaient à Fortran ou Cobol de ne pas montrer
l'utilisation des registres et que, donc, on ne voyait pas comment le
programme fonctionnait.

>
> Lorsqu'on arrive sur un programme qu'on doit maintenir et qu'on n'a pas écrit,
> ça fait une grosse différence. Personnellement, j'hésite toujours à
> accepter un boulot consistant à rajouter des fonctions dans un gros
> code objet, on ne sait jamais sur quoi on va tomber (même lorsque le
> code est a priori propre).

En fait, vous semblez avoir peur de l'approche objet puisque vous dites
: "même lorsque le code est a priori propre".
>
> Que l'on voit très rapidement avec un schéma UML ce qui se passe
> dans un code C++, c'est un fait.

UML est indépendant du langage employé en phase de codage. Il y a des
logiciels de conception UML qui savent générer du SQL, par exemple.

> Que l'on soit capable inteligemmentde rajouter quelque chose dans le même programme est beaucoup plus
> dur parce qu'il est dans les faits très compliqué de voir qui fait
> quoi (mécanisme d'héritage, fonctions virtuelles, polymorphisme,
> toussa...).

Et bien non, c'est facile si l'application est bien conçue. Le
polymorphisme ne s'applique qu'à une hiérarchie de classes, pas entre
des classes de hiérarchies différentes.
Le plus compliqué à comprendre est plutôt la programmation par
délégation (en C++) car il faut passer par la surcharge de l'opérateur
-> pour la faire "intelligemment".

_Remarque_ : il semble, sans vouloir vous froisser, que vous n'ayez pas
complètement assimilé l'approche objet dans sa globalité.

Cette partie de discussion devrait se trouver dans fr.comp.objet mais vu
sa fréquentation...

JKB

unread,
Dec 1, 2011, 4:08:57 PM12/1/11
to
Le Thu, 01 Dec 2011 20:21:35 +0100,
Wykaaa <wyk...@yahoo.fr> écrivait :
J'ai écrit des projets de millions de lignes en procédural avec
comme seules variables globales celles qui sont dans les
gestionnaires de signaux. Procédural ne signifie absolument pas
qu'il y a des vrais bouts de variables globales dedans.

> et du code objet bien fichu (très grande
> modularité avec des dizaines de milliers de classes, comme j'en ai vu,
> utilisation judicieuse du polymorphisme, etc.), je choisis sans hésiter
> le code objet. C'est beaucoup plus facile.

Pas à la relecture. Un code objet est évident pour celui qui le
pond. Pas pour celui qui le relit.
J'aimerais bien qu'on m'explique sans rire pourquoi.

> (au sens objet du terme : faible couplage
> entre classes ou modules et forte cohésion interne de chaque classe ou
> module. Une classe est censée représenter et implémenter une et une
> seule "abstraction" au sens de Grady Booch).
> Cependant si l'on respecte les principes de l'approche objet :
> abstraction, encapsulation, modularité (faible couplage, forte cohésion)
> et hiérarchie (agrégation, composition et héritage) alors la maintenance
> d'un code objet est extrêmement plus facile que celle d'un code
> impératif qui se présente bien souvent comme un vrai plat de spaghettis.
> Dire que "il est plus facile de voir les enchaînements logiques dans le
> détail dans un code procédural" me fait penser aux programmeurs en
> assembleur qui reprochaient à Fortran ou Cobol de ne pas montrer
> l'utilisation des registres et que, donc, on ne voyait pas comment le
> programme fonctionnait.

Sauf que lorsque tu as un gros projet avec des millions de lignes en
C++, des héritages dans tous les sens, des templates en
veux-tu-en-voilà, je te mets au _défi_, de voir assez finement qui
fait quoi et de mettre tes modifications au bon endroit. Lorsque tu
as passé une grosse semaine à essayer de comprendre comment tel bout
de code fonctionne parce que tu as devant toi une poupée russe
d'objets, tu termines invariablement par faire un truc à l'arrache
parce qu'il faut bien que ça fonctionne. J'ai personnellement bossé
sur du code procédural qui avait déjà quarante ans de vie derrière
lui et qui était impécable à tous les points de vue. Je n'ai encore
jamais vu un code objet un peu ancien irréprochable. Je ne dis pas
que ça n'existe pas, simplement que je n'en ai jamais vu.

>> Lorsqu'on arrive sur un programme qu'on doit maintenir et qu'on n'a pas écrit,
>> ça fait une grosse différence. Personnellement, j'hésite toujours à
>> accepter un boulot consistant à rajouter des fonctions dans un gros
>> code objet, on ne sait jamais sur quoi on va tomber (même lorsque le
>> code est a priori propre).
>
> En fait, vous semblez avoir peur de l'approche objet puisque vous dites
>: "même lorsque le code est a priori propre".

Je n'ai pas peur de l'approche objet, je trouve après pas mal
d'années à naviguer entre l'objet et le procédural que l'approche
objet n'est destinée qu'à avoir des foultitudes de programmeurs pas
cher sur le marché et qu'au final c'est une mauvaise réponse à une
bonne question. Je peux développer si nécessaire.

>> Que l'on voit très rapidement avec un schéma UML ce qui se passe
>> dans un code C++, c'est un fait.
>
> UML est indépendant du langage employé en phase de codage. Il y a des
> logiciels de conception UML qui savent générer du SQL, par exemple.

Je parle d'objet, pas de SQL.

>> Que l'on soit capable inteligemmentde rajouter quelque chose dans le même programme est beaucoup plus
>> dur parce qu'il est dans les faits très compliqué de voir qui fait
>> quoi (mécanisme d'héritage, fonctions virtuelles, polymorphisme,
>> toussa...).
>
> Et bien non, c'est facile si l'application est bien conçue. Le
> polymorphisme ne s'applique qu'à une hiérarchie de classes, pas entre
> des classes de hiérarchies différentes.
> Le plus compliqué à comprendre est plutôt la programmation par
> délégation (en C++) car il faut passer par la surcharge de l'opérateur
> -> pour la faire "intelligemment".
>
> _Remarque_ : il semble, sans vouloir vous froisser, que vous n'ayez pas
> complètement assimilé l'approche objet dans sa globalité.

Je pense au contraire que si. J'ai très bien assimilé l'approche
objet (et l'approche procédurale) et c'est bien pour cela que je me
permets de critiquer l'approche objet. Par ailleurs, si on pouvait
éviter le C++, parce qu'un langage où il faut mettre les
constructeurs de copie en purement virtuel pour éviter qu'il fasse
des tas de trucs dans mon dos n'est _pas_ un bon langage.

> Cette partie de discussion devrait se trouver dans fr.comp.objet mais vu
> sa fréquentation...

Wykaaa

unread,
Dec 2, 2011, 3:45:06 PM12/2/11
to
JKB a écrit :
Excusez-moi, j'ai oublié "mal fichu", entre "procédural" et "où il y a
des milliers...". Evidemment que tous les codes procéduraux ne sont pas
de cette nature.
>
>> et du code objet bien fichu (très grande
>> modularité avec des dizaines de milliers de classes, comme j'en ai vu,
>> utilisation judicieuse du polymorphisme, etc.), je choisis sans hésiter
>> le code objet. C'est beaucoup plus facile.
>
> Pas à la relecture. Un code objet est évident pour celui qui le
> pond. Pas pour celui qui le relit.

Pas du tout. J'ai fait des audits de codes objets dans lesquels je
n'avais pas écrit une ligne. Il y en a que je comprenais très aisément.
J'ai expliqué pourquoi :
1) Une classe = une abstraction
2) Modularité = faible couplage entre classes + forte cohésion de chaque
classe
3) encapsulation (qui participe au faible couplage)

C'est justement l'ensemble de tous ces principes qui fait que l'on sait
exactement où faire les modifications et détecter plus rapidement
l'origine des défauts.

>
>> (au sens objet du terme : faible couplage
>> entre classes ou modules et forte cohésion interne de chaque classe ou
>> module. Une classe est censée représenter et implémenter une et une
>> seule "abstraction" au sens de Grady Booch).
>> Cependant si l'on respecte les principes de l'approche objet :
>> abstraction, encapsulation, modularité (faible couplage, forte cohésion)
>> et hiérarchie (agrégation, composition et héritage) alors la maintenance
>> d'un code objet est extrêmement plus facile que celle d'un code
>> impératif qui se présente bien souvent comme un vrai plat de spaghettis.
>> Dire que "il est plus facile de voir les enchaînements logiques dans le
>> détail dans un code procédural" me fait penser aux programmeurs en
>> assembleur qui reprochaient à Fortran ou Cobol de ne pas montrer
>> l'utilisation des registres et que, donc, on ne voyait pas comment le
>> programme fonctionnait.
>
> Sauf que lorsque tu as un gros projet avec des millions de lignes en
> C++, des héritages dans tous les sens,

Il n'y a pas d'héritage dans tous les sens puisque les classes
participant à l'héritage sont organisées en hiérarchie. De plus
l'héritage (comme la composition) respecte les propriétés d'une relation
d'ordre stricte. Il n'y a jamais d'héritage "transversal" entre des
hiérarchies d'héritage différentes.

> des templates en veux-tu-en-voilà,

Les templates servent à la réutilisabilté et l'héritage à la
factorisation. Ce n'est pas pareil. Les templates sont essentiels pour
ne pas dupliquer du code par copier/coller ce qui fabrique du code non
maintenable s'il y a un défaut dans le code dupliqué, comme je l'ai vu,
jusqu'à une dizaine d'exemplaires dans des fichiers différents.

> je te mets au _défi_, de voir assez finement qui fait quoi
> et de mettre tes modifications au bon endroit.

Je l'ai fait pendant presque 10 ans dans du code objet et je n'ai jamais
eu de souci. Il faut que la phase de conception UML soir impeccable. Si
ce n'est pas le cas, alors, oui, les tâches de modifications peuvent
devenir difficiles.


> Lorsque tu as passé une grosse semaine à essayer de comprendre comment tel bout
> de code fonctionne parce que tu as devant toi une poupée russe
> d'objets, tu termines invariablement par faire un truc à l'arrache
> parce qu'il faut bien que ça fonctionne.

Mettre une semaine à comprendre un bout de code objet montre une
méconnaissance de l'approche objet. Tu parles de "poupées russes
d'objets" mais c'est toujours comme cela quand le code (et la
conception) est bien fichu.

> J'ai personnellement bossé sur du code procédural qui avait déjà quarante ans de vie derrière
> lui et qui était impécable à tous les points de vue. Je n'ai encore
> jamais vu un code objet un peu ancien irréprochable. Je ne dis pas
> que ça n'existe pas, simplement que je n'en ai jamais vu.

Moi j'en ai vu beaucoup mais c'est dans des domaines sensibles :
missiles, avionique, satellites de communication, transport d'énergie
principalement où la fiabilité est le facteur qualité numéro un.
>
>>> Lorsqu'on arrive sur un programme qu'on doit maintenir et qu'on n'a pas écrit,
>>> ça fait une grosse différence. Personnellement, j'hésite toujours à
>>> accepter un boulot consistant à rajouter des fonctions dans un gros
>>> code objet, on ne sait jamais sur quoi on va tomber (même lorsque le
>>> code est a priori propre).
>> En fait, vous semblez avoir peur de l'approche objet puisque vous dites
>> : "même lorsque le code est a priori propre".
>
> Je n'ai pas peur de l'approche objet, je trouve après pas mal
> d'années à naviguer entre l'objet et le procédural que l'approche
> objet n'est destinée qu'à avoir des foultitudes de programmeurs pas
> cher sur le marché et qu'au final c'est une mauvaise réponse à une
> bonne question. Je peux développer si nécessaire.

Oui développe parce que des programmeurs pas chers dans les applications
écrites en objets pour les domaines que j'ai cités, je n'en ai pas vus
beaucoup...
>
>>> Que l'on voit très rapidement avec un schéma UML ce qui se passe
>>> dans un code C++, c'est un fait.
>> UML est indépendant du langage employé en phase de codage. Il y a des
>> logiciels de conception UML qui savent générer du SQL, par exemple.
>
> Je parle d'objet, pas de SQL.

Je voulais te montrer que UML n'est pas forcément lié au langage ni même
aux langages objet puisque certains logiciels de conception UML savent
générer du SQL qui n'est ni un langage objet, ni même un langage Turing
complet (i.e. on ne sait pas exprimer tous les algorithmes existants
dans ce langage : balayage récursif d'arbre, par exemple et c'est pour
cela, entre autre, qu'existe le PL au-dessus de SQL).
>
>>> Que l'on soit capable inteligemmentde rajouter quelque chose dans le même programme est beaucoup plus
>>> dur parce qu'il est dans les faits très compliqué de voir qui fait
>>> quoi (mécanisme d'héritage, fonctions virtuelles, polymorphisme,
>>> toussa...).
>> Et bien non, c'est facile si l'application est bien conçue. Le
>> polymorphisme ne s'applique qu'à une hiérarchie de classes, pas entre
>> des classes de hiérarchies différentes.
>> Le plus compliqué à comprendre est plutôt la programmation par
>> délégation (en C++) car il faut passer par la surcharge de l'opérateur
>> -> pour la faire "intelligemment".
>>
>> _Remarque_ : il semble, sans vouloir vous froisser, que vous n'ayez pas
>> complètement assimilé l'approche objet dans sa globalité.
>
> Je pense au contraire que si. J'ai très bien assimilé l'approche
> objet (et l'approche procédurale) et c'est bien pour cela que je me
> permets de critiquer l'approche objet. Par ailleurs, si on pouvait
> éviter le C++, parce qu'un langage où il faut mettre les
> constructeurs de copie en purement virtuel pour éviter qu'il fasse
> des tas de trucs dans mon dos n'est _pas_ un bon langage.

C'est bien ce que je disais, tu ne maîtrises pas totalement ni
l'approche objet ni le C++ ou tu suis aveuglément les préceptes des
soi-disant "gourous" qui parlent de classe canonique, etc.sans avoir
jamais réellement trempé dans de gros projets objets.
Les classes qui doivent posséder des constructeurs de copie (et aussi la
surcharge de l'affectation) sont celles dans lesquelles il y a de
l'allocation dynamique de mémoire dans les constructeurs.
De plus un constructeur (en C++) ne peut jamais être virtuel (pur ou pas
d'ailleurs). Peut-être voulais-tu dire destructeur car, oui, il faut des
destructeurs virtuels dans ce cas pour libérer en cascade les objets
alloués dynamiquement et faire agir le polymorphisme à la destruction
des objets. Rien que de plus normal dans un cadre objet tout à fait
ordinaire.

Le problème des constructeurs de copie c'est qu'ils sont appelés à
chaque fois qu'on crée une copie d'une instance de la classe à laquelle
ils appartiennent (en particulier quand on passe des instances de classe
par valeur). Le moyen d'éviter cela est de passer les instances de
classe par référence constante partout où l'on passe par valeur. Le
passage par référence constante devrait être le mode de passage par
défaut, en C++. Hélas, pour des raisons de compatibilité avec le langage
C, il a été décidé de conserver le passage par valeur par défaut.

Wykaaa

JKB

unread,
Dec 3, 2011, 4:15:55 AM12/3/11
to
Le Fri, 02 Dec 2011 21:45:06 +0100,
Wykaaa <wyk...@yahoo.fr> écrivait :
> JKB a écrit :
>>
>> J'ai écrit des projets de millions de lignes en procédural avec
>> comme seules variables globales celles qui sont dans les
>> gestionnaires de signaux. Procédural ne signifie absolument pas
>> qu'il y a des vrais bouts de variables globales dedans.
>
> Excusez-moi, j'ai oublié "mal fichu", entre "procédural" et "où il y a
> des milliers...". Evidemment que tous les codes procéduraux ne sont pas
> de cette nature.

Et heureusement.

>>> et du code objet bien fichu (très grande
>>> modularité avec des dizaines de milliers de classes, comme j'en ai vu,
>>> utilisation judicieuse du polymorphisme, etc.), je choisis sans hésiter
>>> le code objet. C'est beaucoup plus facile.
>>
>> Pas à la relecture. Un code objet est évident pour celui qui le
>> pond. Pas pour celui qui le relit.
>
> Pas du tout. J'ai fait des audits de codes objets dans lesquels je
> n'avais pas écrit une ligne. Il y en a que je comprenais très aisément.

Comprenez-vous la différence entre 'il y en a que je comprenais très
aisément' et 'je les comprends tous très aisément'. Effectivement,
il y en a.

<snip>

>>> Il est vrai que le code objet est plus "atomisé", justement parce qu'il
>>> est censé être plus modulaire
>>
>> J'aimerais bien qu'on m'explique sans rire pourquoi.
>
> J'ai expliqué pourquoi :
> 1) Une classe = une abstraction

Mouais.

> 2) Modularité = faible couplage entre classes + forte cohésion de chaque
> classe

Mouais.

> 3) encapsulation (qui participe au faible couplage)

Rien à voir avec un code objet. L'encapsulation se fait aussi en
Fortran77 qui n'est à ma connaissance pas objet pour un sou.

> C'est justement l'ensemble de tous ces principes qui fait que l'on sait
> exactement où faire les modifications et détecter plus rapidement
> l'origine des défauts.

Non. Là, aujourd'hui, je bosse sur un code (plus exactement, je
passe après une équipe de developpeurs qui est partie) comportant
plusieurs milliers de classes avec du polymorphisme, des templates
et des tas de choses typiques du C++, de celles que les programmeurs
fous mettent partout pour se faire plaisir. Personnellement, je suis
freelance et je dois dire aussi que je passe après plusieurs autres
qui ont jeté l'éponge. Ça fait maintenant deux mois que je me tape
de la relecture de code. Toutes les classes sont bien écrites, mais
avec des héritages dans tous les sens et des surcharges du même
tonneau. Au final, tu as vraiment du mal à voir qui fait quoi
d'autant que le coup du 'virtual' en C++ est un truc
particulièrement piégeux.

Il y a des défauts dans le code, un tas de défaut de conception
(variables d'instances qui ne sont pas dans la bonne classe) ou
défaut plus graves (entre autres fonctions virtuelles qui sont écrasées
par celles de la classe fille, mais il faut appeler récursivement
toutes celles des parents), et je ne suis pas sûr, mais alors vraiment
pas sûr que je prenne moins de temps à corriger le truc qu'à réécrire
le code 'from scratch'. Et je ne parle que du côté compréhensible du
code, pas encore de l'organisation des classes.

>>> (au sens objet du terme : faible couplage
>>> entre classes ou modules et forte cohésion interne de chaque classe ou
>>> module. Une classe est censée représenter et implémenter une et une
>>> seule "abstraction" au sens de Grady Booch).
>>> Cependant si l'on respecte les principes de l'approche objet :
>>> abstraction, encapsulation, modularité (faible couplage, forte cohésion)
>>> et hiérarchie (agrégation, composition et héritage) alors la maintenance
>>> d'un code objet est extrêmement plus facile que celle d'un code
>>> impératif qui se présente bien souvent comme un vrai plat de spaghettis.
>>> Dire que "il est plus facile de voir les enchaînements logiques dans le
>>> détail dans un code procédural" me fait penser aux programmeurs en
>>> assembleur qui reprochaient à Fortran ou Cobol de ne pas montrer
>>> l'utilisation des registres et que, donc, on ne voyait pas comment le
>>> programme fonctionnait.
>>
>> Sauf que lorsque tu as un gros projet avec des millions de lignes en
>> C++, des héritages dans tous les sens,
>
> Il n'y a pas d'héritage dans tous les sens puisque les classes
> participant à l'héritage sont organisées en hiérarchie.

Quand je dis héritages dans tous les sens, c'est naturellement en
hiérarchie. Ne faites pas semblant de ne pas avoir compris.
Lorsqu'il y a plusieurs milliers de classes qui héritent les unes
des autres (et certaines de plusieurs classes mères), le résultat
peu être assez rigolo à comprendre.

> De plus
> l'héritage (comme la composition) respecte les propriétés d'une relation
> d'ordre stricte. Il n'y a jamais d'héritage "transversal" entre des
> hiérarchies d'héritage différentes.

Où ai-je prétendu le contraire ?

>> des templates en veux-tu-en-voilà,
>
> Les templates servent à la réutilisabilté et l'héritage à la
> factorisation. Ce n'est pas pareil. Les templates sont essentiels pour
> ne pas dupliquer du code par copier/coller ce qui fabrique du code non
> maintenable s'il y a un défaut dans le code dupliqué, comme je l'ai vu,
> jusqu'à une dizaine d'exemplaires dans des fichiers différents.

Certes, les templates, ça peut être pratique. Ça ne concourt
généralement pas à la lisibilité du code.

>> je te mets au _défi_, de voir assez finement qui fait quoi
>> et de mettre tes modifications au bon endroit.
>
> Je l'ai fait pendant presque 10 ans dans du code objet et je n'ai jamais
> eu de souci. Il faut que la phase de conception UML soir impeccable. Si
> ce n'est pas le cas, alors, oui, les tâches de modifications peuvent
> devenir difficiles.

Ça fait un peu plus de dix ans que je fais ça (certes pas à plein
temps). Je n'ai encore jamais vu un code objet, quitte à me répéter,
qui soit facilement maintenable en l'absence de l'équipe de dev
initiale. Comme vous le signalez, il faut d'une part que la
modélisation soit parfaite, mais il faut aussi que le code soit
documenté. La plupart du temps, la seule documentation à jour à ma
disposition est le code lui-même.

>> Lorsque tu as passé une grosse semaine à essayer de comprendre comment tel bout
>> de code fonctionne parce que tu as devant toi une poupée russe
>> d'objets, tu termines invariablement par faire un truc à l'arrache
>> parce qu'il faut bien que ça fonctionne.
>
> Mettre une semaine à comprendre un bout de code objet montre une
> méconnaissance de l'approche objet. Tu parles de "poupées russes
> d'objets" mais c'est toujours comme cela quand le code (et la
> conception) est bien fichu.

Merci de ne pas me prendre pour un débutant. Encore une fois, je me
permets de critiquer l'approche objet parce que je la connais
parfaitement. Le côté poupée russe est intrinsèque au modèle objet,
c'est une évidence. En revanche, lorsque la modélisation est
bancale, les poupées russes sont inextricables.

>> J'ai personnellement bossé sur du code procédural qui avait déjà quarante ans de vie derrière
>> lui et qui était impécable à tous les points de vue. Je n'ai encore
>> jamais vu un code objet un peu ancien irréprochable. Je ne dis pas
>> que ça n'existe pas, simplement que je n'en ai jamais vu.
>
> Moi j'en ai vu beaucoup mais c'est dans des domaines sensibles :
> missiles, avionique, satellites de communication, transport d'énergie
> principalement où la fiabilité est le facteur qualité numéro un.

Tiens, justement, j'ai bossé dans le secteur des satellites, des
missiles et actuellement pour le transport d'énergie. Les autres, je
ne connais pas donc je n'en parlerais pas. Dans ces trois domaines,
j'ai rarement vu du code lisible (je n'ai pas dit qu'il n'était pas
fiable, hein) et maintenable facilement.

>>>> Lorsqu'on arrive sur un programme qu'on doit maintenir et qu'on n'a pas écrit,
>>>> ça fait une grosse différence. Personnellement, j'hésite toujours à
>>>> accepter un boulot consistant à rajouter des fonctions dans un gros
>>>> code objet, on ne sait jamais sur quoi on va tomber (même lorsque le
>>>> code est a priori propre).
>>> En fait, vous semblez avoir peur de l'approche objet puisque vous dites
>>> : "même lorsque le code est a priori propre".
>>
>> Je n'ai pas peur de l'approche objet, je trouve après pas mal
>> d'années à naviguer entre l'objet et le procédural que l'approche
>> objet n'est destinée qu'à avoir des foultitudes de programmeurs pas
>> cher sur le marché et qu'au final c'est une mauvaise réponse à une
>> bonne question. Je peux développer si nécessaire.
>
> Oui développe parce que des programmeurs pas chers dans les applications
> écrites en objets pour les domaines que j'ai cités, je n'en ai pas vus
> beaucoup...

Aujourd'hui, dans une boîte que je ne citerai pas qui travaille dans
le transport d'énergie, le tarif journalier du freelance est de 250
euros HT par jour. En région parisienne. Je te laisse conclure
quant à la qualité du boulot.

Maintenant, l'objet, c'est un paradigme qui fait que les procédures
procèdent des données et non le contraire comme dans les approches
fonctionnelles ou procédurales. Dit autrement, cela revient à
laisser tomber l'éternelle question de savoir à qui appartient telle
ou telle donnée sans se préocupper dans les détails de tout ce qui
est affectation et libération de mémoire (un simple delete sur un
objet vire toute la mémoire associée à cet objet). L'objet permet
aussi de ne jamais se poser les questions qui fâchent en utilisant
des fonctions toutes faites de la libcstd++. Au final, on développe
vite, mais le résultat est inefficace et consommateur de ressources.
La formation du développeur de base est aussi plus rapide (pas
besoin d'intégrer les mécanismes de base des listes chaînées, des
arbres et de toutes les joyeusetés de la programmation).

>>>> Que l'on voit très rapidement avec un schéma UML ce qui se passe
>>>> dans un code C++, c'est un fait.
>>> UML est indépendant du langage employé en phase de codage. Il y a des
>>> logiciels de conception UML qui savent générer du SQL, par exemple.
>>
>> Je parle d'objet, pas de SQL.
>
> Je voulais te montrer que UML n'est pas forcément lié au langage ni même
> aux langages objet puisque certains logiciels de conception UML savent
> générer du SQL qui n'est ni un langage objet, ni même un langage Turing
> complet (i.e. on ne sait pas exprimer tous les algorithmes existants
> dans ce langage : balayage récursif d'arbre, par exemple et c'est pour
> cela, entre autre, qu'existe le PL au-dessus de SQL).

Où ai-je prétendu le contraire ?

>>>> Que l'on soit capable inteligemmentde rajouter quelque chose dans le même programme est beaucoup plus
>>>> dur parce qu'il est dans les faits très compliqué de voir qui fait
>>>> quoi (mécanisme d'héritage, fonctions virtuelles, polymorphisme,
>>>> toussa...).
>>> Et bien non, c'est facile si l'application est bien conçue. Le
>>> polymorphisme ne s'applique qu'à une hiérarchie de classes, pas entre
>>> des classes de hiérarchies différentes.
>>> Le plus compliqué à comprendre est plutôt la programmation par
>>> délégation (en C++) car il faut passer par la surcharge de l'opérateur
>>> -> pour la faire "intelligemment".
>>>
>>> _Remarque_ : il semble, sans vouloir vous froisser, que vous n'ayez pas
>>> complètement assimilé l'approche objet dans sa globalité.
>>
>> Je pense au contraire que si. J'ai très bien assimilé l'approche
>> objet (et l'approche procédurale) et c'est bien pour cela que je me
>> permets de critiquer l'approche objet. Par ailleurs, si on pouvait
>> éviter le C++, parce qu'un langage où il faut mettre les
>> constructeurs de copie en purement virtuel pour éviter qu'il fasse
>> des tas de trucs dans mon dos n'est _pas_ un bon langage.
>
> C'est bien ce que je disais, tu ne maîtrises pas totalement ni
> l'approche objet ni le C++ ou tu suis aveuglément les préceptes des
> soi-disant "gourous" qui parlent de classe canonique, etc.sans avoir
> jamais réellement trempé dans de gros projets objets.

Si tu le dis...

> Les classes qui doivent posséder des constructeurs de copie (et aussi la
> surcharge de l'affectation) sont celles dans lesquelles il y a de
> l'allocation dynamique de mémoire dans les constructeurs.
> De plus un constructeur (en C++) ne peut jamais être virtuel (pur ou pas
> d'ailleurs). Peut-être voulais-tu dire destructeur car, oui, il faut des
> destructeurs virtuels dans ce cas pour libérer en cascade les objets
> alloués dynamiquement et faire agir le polymorphisme à la destruction
> des objets. Rien que de plus normal dans un cadre objet tout à fait
> ordinaire.

Je ne parle pas de _constructeur_, mais de _constructeur de copie_.
Je sais parfaitement qu'un constructeur ne peut pas être virtuel et
qu'il est de bon ton que le destructeur le soit.

> Le problème des constructeurs de copie c'est qu'ils sont appelés à
> chaque fois qu'on crée une copie d'une instance de la classe à laquelle
> ils appartiennent (en particulier quand on passe des instances de classe
> par valeur). Le moyen d'éviter cela est de passer les instances de
> classe par référence constante partout où l'on passe par valeur. Le
> passage par référence constante devrait être le mode de passage par
> défaut, en C++. Hélas, pour des raisons de compatibilité avec le langage
> C, il a été décidé de conserver le passage par valeur par défaut.

C'est encore une pierre dans le jardin du C++. Merci d'ajouter de
l'eau à mon moulin.

Wykaaa

unread,
Dec 3, 2011, 7:54:44 AM12/3/11
to
JKB a écrit :
L'encapsulation, au sens objet du terme, consiste à mettre
systématiquement les attributs de classe dans la partie "private" et à
coder des "getteurs" et des "setteurs" pour les accéder et modifier les
valeurs. Ca n'a pas grand chose à voir avec la pseudo-encapsulation
qu'on peut faire en Fortran77.
>
>> C'est justement l'ensemble de tous ces principes qui fait que l'on sait
>> exactement où faire les modifications et détecter plus rapidement
>> l'origine des défauts.
>
> Non. Là, aujourd'hui, je bosse sur un code (plus exactement, je
> passe après une équipe de developpeurs qui est partie) comportant
> plusieurs milliers de classes avec du polymorphisme, des templates
> et des tas de choses typiques du C++, de celles que les programmeurs
> fous mettent partout pour se faire plaisir.

Ce n'est pas pour se faire plaisir mais pour que le code soit de
meilleure qualité. Je n'ai jamais vu un programmeur C++ débutant mettre
des templates et faire du polymorphisme partout. C'est plutôt le
contraire. Un débutant en C++ va avoir tendance à coder comme en C, ce
qui est la pire des choses à faire en C++.

En général, les programmeurs C++ n'utilisent pas toutes ces choses pour
"se faire plaisir" mais par nécessité d'appliquer correctement l'objet
et la réutilisation (la généricité existe dans des langages non objets
comme ADA83). Quant au polymorphisme, il existe aussi dans des langages
non objet comme ML ou Caml.


> Personnellement, je suis freelance et je dois dire aussi que je passe après plusieurs autres
> qui ont jeté l'éponge. Ça fait maintenant deux mois que je me tape
> de la relecture de code. Toutes les classes sont bien écrites, mais
> avec des héritages dans tous les sens et des surcharges du même
> tonneau. Au final, tu as vraiment du mal à voir qui fait quoi
> d'autant que le coup du 'virtual' en C++ est un truc
> particulièrement piégeux.

Ben non. Le virtuel n'est pas piégeux puisque ça veut juste dire que la
fonction est polymorphe, ce qui est le défaut en Smalltalk, par exemple.
>
> Il y a des défauts dans le code, un tas de défaut de conception
> (variables d'instances qui ne sont pas dans la bonne classe)

S'il y a des attributs de classe qui ne sont pas dans la bonne classe,
cela veut dire que le principe de forte cohésion, qui sous-tend la
modularité objet, n'est pas respecté.

> ou défaut plus graves (entre autres fonctions virtuelles qui sont écrasées
> par celles de la classe fille,

Ca veut dire quoi "écrasée" ? surchargée avec une autre signature ? Je
ne comprends pas ce que tu veux dire.



> mais il faut appeler récursivement toutes celles des parents), et je ne suis pas sûr, mais alors vraiment
> pas sûr que je prenne moins de temps à corriger le truc qu'à réécrire
> le code 'from scratch'. Et je ne parle que du côté compréhensible du
> code, pas encore de l'organisation des classes.

Visiblement la conception n'est pas bonne.
>
>>>> (au sens objet du terme : faible couplage
>>>> entre classes ou modules et forte cohésion interne de chaque classe ou
>>>> module. Une classe est censée représenter et implémenter une et une
>>>> seule "abstraction" au sens de Grady Booch).
>>>> Cependant si l'on respecte les principes de l'approche objet :
>>>> abstraction, encapsulation, modularité (faible couplage, forte cohésion)
>>>> et hiérarchie (agrégation, composition et héritage) alors la maintenance
>>>> d'un code objet est extrêmement plus facile que celle d'un code
>>>> impératif qui se présente bien souvent comme un vrai plat de spaghettis.
>>>> Dire que "il est plus facile de voir les enchaînements logiques dans le
>>>> détail dans un code procédural" me fait penser aux programmeurs en
>>>> assembleur qui reprochaient à Fortran ou Cobol de ne pas montrer
>>>> l'utilisation des registres et que, donc, on ne voyait pas comment le
>>>> programme fonctionnait.
>>> Sauf que lorsque tu as un gros projet avec des millions de lignes en
>>> C++, des héritages dans tous les sens,
>> Il n'y a pas d'héritage dans tous les sens puisque les classes
>> participant à l'héritage sont organisées en hiérarchie.
>
> Quand je dis héritages dans tous les sens, c'est naturellement en
> hiérarchie. Ne faites pas semblant de ne pas avoir compris.
> Lorsqu'il y a plusieurs milliers de classes qui héritent les unes
> des autres (et certaines de plusieurs classes mères), le résultat
> peu être assez rigolo à comprendre.

Avoir plusieurs milliers de sous-classes d'une classe n'est pas de la
bonne conception. Ceci confirme que l'application a été mal conçue.
>
>> De plus
>> l'héritage (comme la composition) respecte les propriétés d'une relation
>> d'ordre stricte. Il n'y a jamais d'héritage "transversal" entre des
>> hiérarchies d'héritage différentes.
>
> Où ai-je prétendu le contraire ?

Tu disais "dans tous les sens" (ça inclus le transversal...)
>
>>> des templates en veux-tu-en-voilà,
>> Les templates servent à la réutilisabilté et l'héritage à la
>> factorisation. Ce n'est pas pareil. Les templates sont essentiels pour
>> ne pas dupliquer du code par copier/coller ce qui fabrique du code non
>> maintenable s'il y a un défaut dans le code dupliqué, comme je l'ai vu,
>> jusqu'à une dizaine d'exemplaires dans des fichiers différents.
>
> Certes, les templates, ça peut être pratique. Ça ne concourt
> généralement pas à la lisibilité du code.

Aujourd'hui l'utilisation des templates est incontournable, au moins
pour fabriquer des bibliothèques de classes. Regarde les bibliothèques
"officielles" C++. La lisibilité des templates est un problème C++ (qui
est plus verbeux qu'ADA pour leur mise en oeuvre, un comble !) pas un
problème du concept lui-même (qui, encore une fois, n'est pas un concept
objet).
>
>>> je te mets au _défi_, de voir assez finement qui fait quoi
>>> et de mettre tes modifications au bon endroit.
>> Je l'ai fait pendant presque 10 ans dans du code objet et je n'ai jamais
>> eu de souci. Il faut que la phase de conception UML soir impeccable. Si
>> ce n'est pas le cas, alors, oui, les tâches de modifications peuvent
>> devenir difficiles.
>
> Ça fait un peu plus de dix ans que je fais ça (certes pas à plein
> temps). Je n'ai encore jamais vu un code objet, quitte à me répéter,
> qui soit facilement maintenable en l'absence de l'équipe de dev
> initiale. Comme vous le signalez, il faut d'une part que la
> modélisation soit parfaite, mais il faut aussi que le code soit
> documenté. La plupart du temps, la seule documentation à jour à ma
> disposition est le code lui-même.

C'est un défaut des projets, en général...
Justement, dans ces domaines il faut des programmeurs expérimentés ce
qui, je te le concède, n'est pas toujours le cas. Mais là encore c'est
un problème de gestion de projet et d'argent : lors des appels d'offre,
le client choisit presque toujours le "moins disant".
>
>>>>> Lorsqu'on arrive sur un programme qu'on doit maintenir et qu'on n'a pas écrit,
>>>>> ça fait une grosse différence. Personnellement, j'hésite toujours à
>>>>> accepter un boulot consistant à rajouter des fonctions dans un gros
>>>>> code objet, on ne sait jamais sur quoi on va tomber (même lorsque le
>>>>> code est a priori propre).
>>>> En fait, vous semblez avoir peur de l'approche objet puisque vous dites
>>>> : "même lorsque le code est a priori propre".
>>> Je n'ai pas peur de l'approche objet, je trouve après pas mal
>>> d'années à naviguer entre l'objet et le procédural que l'approche
>>> objet n'est destinée qu'à avoir des foultitudes de programmeurs pas
>>> cher sur le marché et qu'au final c'est une mauvaise réponse à une
>>> bonne question. Je peux développer si nécessaire.
>> Oui développe parce que des programmeurs pas chers dans les applications
>> écrites en objets pour les domaines que j'ai cités, je n'en ai pas vus
>> beaucoup...
>
> Aujourd'hui, dans une boîte que je ne citerai pas qui travaille dans
> le transport d'énergie, le tarif journalier du freelance est de 250
> euros HT par jour. En région parisienne. Je te laisse conclure
> quant à la qualité du boulot.

Il faut des programmeurs ex-pé-ri-men-tés dans ces domaines (voir
ci-dessus).
>
> Maintenant, l'objet, c'est un paradigme qui fait que les procédures
> procèdent des données et non le contraire comme dans les approches
> fonctionnelles ou procédurales. Dit autrement, cela revient à
> laisser tomber l'éternelle question de savoir à qui appartient telle
> ou telle donnée

Non justement car il faut respecter les principes une classe=une
abstraction et la forte cohésion interne de chaque classe (tu as fait
"mouais" à tous ces principes qui sont fondamentaux en approche objet.
Si on ne les respecte pas strictement alors on ne fait pas de l'objet
mais des immondices dans lesquels tu sembles être tombé involontairement :-)

> sans se préocupper dans les détails de tout ce qui est affectation et
> libération de mémoire (un simple delete sur un
> objet vire toute la mémoire associée à cet objet.

Ben non justement. Pas s'il y a du polymorphisme avec allocation mémoire
dynamique à tous les étages de l'héritage. Il faut que les destructeurs
soient virtuels. On doit donc s'en préoccuper !

> L'objet permet aussi de ne jamais se poser les questions qui fâchent en utilisant
> des fonctions toutes faites de la libcstd++. Au final, on développe
> vite, mais le résultat est inefficace et consommateur de ressources.
> La formation du développeur de base est aussi plus rapide (pas
> besoin d'intégrer les mécanismes de base des listes chaînées, des
> arbres et de toutes les joyeusetés de la programmation).

Utilisation de bibliothèques ou pas, pour moi, un programmeur qui ne
connaît pas un minimum de l'algorithmique associée aux listes chaînées
ou aux arbres n'est pas un "vrai" programmeur. J'ai toujours vérifié ce
genre de connaissances lors du recrutement de programmeurs.
>
>>>>> Que l'on voit très rapidement avec un schéma UML ce qui se passe
>>>>> dans un code C++, c'est un fait.
>>>> UML est indépendant du langage employé en phase de codage. Il y a des
>>>> logiciels de conception UML qui savent générer du SQL, par exemple.
>>> Je parle d'objet, pas de SQL.
>> Je voulais te montrer que UML n'est pas forcément lié au langage ni même
>> aux langages objet puisque certains logiciels de conception UML savent
>> générer du SQL qui n'est ni un langage objet, ni même un langage Turing
>> complet (i.e. on ne sait pas exprimer tous les algorithmes existants
>> dans ce langage : balayage récursif d'arbre, par exemple et c'est pour
>> cela, entre autre, qu'existe le PL au-dessus de SQL).
>
> Où ai-je prétendu le contraire ?

Tu me reprochais de parler de SQL et pas d'objet; je te justifie pourquoi.
Le constructeur de copie est, avant tout,un constructeur et, à ce titre,
il ne peut être virtuel...
>
>> Le problème des constructeurs de copie c'est qu'ils sont appelés à
>> chaque fois qu'on crée une copie d'une instance de la classe à laquelle
>> ils appartiennent (en particulier quand on passe des instances de classe
>> par valeur). Le moyen d'éviter cela est de passer les instances de
>> classe par référence constante partout où l'on passe par valeur. Le
>> passage par référence constante devrait être le mode de passage par
>> défaut, en C++. Hélas, pour des raisons de compatibilité avec le langage
>> C, il a été décidé de conserver le passage par valeur par défaut.
>
> C'est encore une pierre dans le jardin du C++. Merci d'ajouter de
> l'eau à mon moulin.

Si on veut. Chaque langage a ses avantages et ses inconvénients.

Wykaaa

JKB

unread,
Dec 3, 2011, 8:28:00 AM12/3/11
to
Le Sat, 03 Dec 2011 13:54:44 +0100,
Wykaaa <wyk...@yahoo.fr> écrivait :
> JKB a écrit :
>> Mouais.
>>
>>> 3) encapsulation (qui participe au faible couplage)
>>
>> Rien à voir avec un code objet. L'encapsulation se fait aussi en
>> Fortran77 qui n'est à ma connaissance pas objet pour un sou.
>
> L'encapsulation, au sens objet du terme, consiste à mettre
> systématiquement les attributs de classe dans la partie "private" et à
> coder des "getteurs" et des "setteurs" pour les accéder et modifier les
> valeurs. Ca n'a pas grand chose à voir avec la pseudo-encapsulation
> qu'on peut faire en Fortran77.

C'est exactement ce qu'on peut faire à grands coups d'ENTRY en
Fortran.

>>> C'est justement l'ensemble de tous ces principes qui fait que l'on sait
>>> exactement où faire les modifications et détecter plus rapidement
>>> l'origine des défauts.
>>
>> Non. Là, aujourd'hui, je bosse sur un code (plus exactement, je
>> passe après une équipe de developpeurs qui est partie) comportant
>> plusieurs milliers de classes avec du polymorphisme, des templates
>> et des tas de choses typiques du C++, de celles que les programmeurs
>> fous mettent partout pour se faire plaisir.
>
> Ce n'est pas pour se faire plaisir mais pour que le code soit de
> meilleure qualité. Je n'ai jamais vu un programmeur C++ débutant mettre
> des templates et faire du polymorphisme partout. C'est plutôt le
> contraire. Un débutant en C++ va avoir tendance à coder comme en C, ce
> qui est la pire des choses à faire en C++.
>
> En général, les programmeurs C++ n'utilisent pas toutes ces choses pour
> "se faire plaisir" mais par nécessité d'appliquer correctement l'objet
> et la réutilisation (la généricité existe dans des langages non objets
> comme ADA83). Quant au polymorphisme, il existe aussi dans des langages
> non objet comme ML ou Caml.
>

Et ?

>
>> Personnellement, je suis freelance et je dois dire aussi que je passe après plusieurs autres
>> qui ont jeté l'éponge. Ça fait maintenant deux mois que je me tape
>> de la relecture de code. Toutes les classes sont bien écrites, mais
>> avec des héritages dans tous les sens et des surcharges du même
>> tonneau. Au final, tu as vraiment du mal à voir qui fait quoi
>> d'autant que le coup du 'virtual' en C++ est un truc
>> particulièrement piégeux.
>
> Ben non. Le virtuel n'est pas piégeux puisque ça veut juste dire que la
> fonction est polymorphe, ce qui est le défaut en Smalltalk, par exemple.

Et bien si, c'est piégeux. Parce que tu peux avoir une fonction
start dans la classe mère qui fait un tas de choses nécessaire à
l'objet en question. Lorsque tu définis (ou que quelqu'un d'autre le
fait) une fonction start surchargée dans une classe qui hérite de la
première, c'est _piégeux_. Des bourdes comme ça, j'en corrige des
tas et tu serais bien le premier à ne jamais en avoir fait.

>>
>> Il y a des défauts dans le code, un tas de défaut de conception
>> (variables d'instances qui ne sont pas dans la bonne classe)
>
> S'il y a des attributs de classe qui ne sont pas dans la bonne classe,
> cela veut dire que le principe de forte cohésion, qui sous-tend la
> modularité objet, n'est pas respecté.

Ça veut surtout dire que le type qui a codé la classe en question ne
raisonne par de la même façon que le type qui la corrige. Rien de
plus.

>> ou défaut plus graves (entre autres fonctions virtuelles qui sont écrasées
>> par celles de la classe fille,
>
> Ca veut dire quoi "écrasée" ? surchargée avec une autre signature ? Je
> ne comprends pas ce que tu veux dire.

Ça veut dire surchargée, rien d'autre.

>> mais il faut appeler récursivement toutes celles des parents), et je ne suis pas sûr, mais alors vraiment
>> pas sûr que je prenne moins de temps à corriger le truc qu'à réécrire
>> le code 'from scratch'. Et je ne parle que du côté compréhensible du
>> code, pas encore de l'organisation des classes.
>
> Visiblement la conception n'est pas bonne.

Voilà. Dès qu'un truc devient complexe, la conception n'est pas la
bonne. On change de conception, jamais de paradigme, ça demanderait
trop de travail.
Cela n'engage que toi. L'application à laquelle je fais allusion est
un truc qui doit piloter des gazillons de périphériques différents
chez l'habitant. Au mieux, tu as une classe par pilote de
périphérique (et c'est vraiment au mieux) qui hérite de tout un tas
de choses. Actuellement, dans l'application, on a plus de 900 pilotes
différents.

>>
>>> De plus
>>> l'héritage (comme la composition) respecte les propriétés d'une relation
>>> d'ordre stricte. Il n'y a jamais d'héritage "transversal" entre des
>>> hiérarchies d'héritage différentes.
>>
>> Où ai-je prétendu le contraire ?
>
> Tu disais "dans tous les sens" (ça inclus le transversal...)

Sans commentaire.

>>
>>>> des templates en veux-tu-en-voilà,
>>> Les templates servent à la réutilisabilté et l'héritage à la
>>> factorisation. Ce n'est pas pareil. Les templates sont essentiels pour
>>> ne pas dupliquer du code par copier/coller ce qui fabrique du code non
>>> maintenable s'il y a un défaut dans le code dupliqué, comme je l'ai vu,
>>> jusqu'à une dizaine d'exemplaires dans des fichiers différents.
>>
>> Certes, les templates, ça peut être pratique. Ça ne concourt
>> généralement pas à la lisibilité du code.
>
> Aujourd'hui l'utilisation des templates est incontournable, au moins

Non.

> pour fabriquer des bibliothèques de classes.

À la rigueur.
Ce qui contredit ta première assertion. Je sais bien que je suis le
type qu'on appelle lorsqu'un projet est planté, donc mon expérience
n'est peut-être pas représentative, mais ça reste tout de même une
expérience significative.
La réponse est à côté de la plaque. Je ne suis pas en train de
parler d'abstraction mais de préseance.

>> sans se préocupper dans les détails de tout ce qui est affectation et
>> libération de mémoire (un simple delete sur un
>> objet vire toute la mémoire associée à cet objet.
>
> Ben non justement. Pas s'il y a du polymorphisme avec allocation mémoire
> dynamique à tous les étages de l'héritage. Il faut que les destructeurs
> soient virtuels. On doit donc s'en préoccuper !

Le programmeur, in fine, n'a pas à s'en préoccuper. Seul celui qui
code la classe en question doit le savoir. L'intérêt du C++,
c'est justement de cacher au programmeur de genre de choses.
Voir des programmeurs utiliser la libcstd++ avec des listes, des maps et
pleins d'autres choses et ne pas imaginer un instant la gestion
mémoire qui est faite derrière me désole au plus haut point.
Je vais donc dire ça à mon compilo C++. Il ne semble pas le savoir.
Je fais ça pour interdire que le truc décide de faire une copie dans
mon dos (ou que je rate une opération de copie). Je le déclare même
d'office purement virtuel.

>>> Le problème des constructeurs de copie c'est qu'ils sont appelés à
>>> chaque fois qu'on crée une copie d'une instance de la classe à laquelle
>>> ils appartiennent (en particulier quand on passe des instances de classe
>>> par valeur). Le moyen d'éviter cela est de passer les instances de
>>> classe par référence constante partout où l'on passe par valeur. Le
>>> passage par référence constante devrait être le mode de passage par
>>> défaut, en C++. Hélas, pour des raisons de compatibilité avec le langage
>>> C, il a été décidé de conserver le passage par valeur par défaut.
>>
>> C'est encore une pierre dans le jardin du C++. Merci d'ajouter de
>> l'eau à mon moulin.
>
> Si on veut. Chaque langage a ses avantages et ses inconvénients.
>
> Wykaaa

Tonton Th

unread,
Dec 3, 2011, 11:29:59 AM12/3/11
to
On 12/01/2011 08:21 PM, Wykaaa wrote:

> dizaines de milliers de classes,

Oups...

--

Nous vivons dans un monde étrange/
http://foo.bar.quux.over-blog.com/

Wykaaa

unread,
Dec 3, 2011, 3:05:03 PM12/3/11
to
Tonton Th a écrit :
> On 12/01/2011 08:21 PM, Wykaaa wrote:
>
>> dizaines de milliers de classes,
>
> Oups...
>
Quoi Oups ?

C'est la vérité.

Il y avait, dans ce projet, 26 311 classes. C'est le logiciel de
métrologie logicielle Logiscope qui me l'a dit :-)

Dans un logiciel d'environ 3 millions de lignes de code, ça fait, en
moyenne 114 lignes par classes, ce qui est déjà beaucoup.

Wykaaa

unread,
Dec 3, 2011, 3:24:35 PM12/3/11
to
JKB a écrit :
> Le Sat, 03 Dec 2011 13:54:44 +0100,
> Wykaaa <wyk...@yahoo.fr> écrivait :
>> JKB a écrit :
>>> Mouais.
>>>
>>>> 3) encapsulation (qui participe au faible couplage)
>>> Rien à voir avec un code objet. L'encapsulation se fait aussi en
>>> Fortran77 qui n'est à ma connaissance pas objet pour un sou.
>> L'encapsulation, au sens objet du terme, consiste à mettre
>> systématiquement les attributs de classe dans la partie "private" et à
>> coder des "getteurs" et des "setteurs" pour les accéder et modifier les
>> valeurs. Ca n'a pas grand chose à voir avec la pseudo-encapsulation
>> qu'on peut faire en Fortran77.
>
> C'est exactement ce qu'on peut faire à grands coups d'ENTRY en
> Fortran.

Non, pas exactement car le compilateur ne te dira rien si tu accèdes
directement à certaines variables. Avec provate, tu es certain de ne
pouvoir accéder aux attributs autrement que par des accesseurs ou
modifieurs.
>
>>>> C'est justement l'ensemble de tous ces principes qui fait que l'on sait
>>>> exactement où faire les modifications et détecter plus rapidement
>>>> l'origine des défauts.
>>> Non. Là, aujourd'hui, je bosse sur un code (plus exactement, je
>>> passe après une équipe de developpeurs qui est partie) comportant
>>> plusieurs milliers de classes avec du polymorphisme, des templates
>>> et des tas de choses typiques du C++, de celles que les programmeurs
>>> fous mettent partout pour se faire plaisir.
>> Ce n'est pas pour se faire plaisir mais pour que le code soit de
>> meilleure qualité. Je n'ai jamais vu un programmeur C++ débutant mettre
>> des templates et faire du polymorphisme partout. C'est plutôt le
>> contraire. Un débutant en C++ va avoir tendance à coder comme en C, ce
>> qui est la pire des choses à faire en C++.
>>
>> En général, les programmeurs C++ n'utilisent pas toutes ces choses pour
>> "se faire plaisir" mais par nécessité d'appliquer correctement l'objet
>> et la réutilisation (la généricité existe dans des langages non objets
>> comme ADA83). Quant au polymorphisme, il existe aussi dans des langages
>> non objet comme ML ou Caml.
>>
>
> Et ?

Tu semblais "pester" contre le polymorphisme...
>
>>> Personnellement, je suis freelance et je dois dire aussi que je passe après plusieurs autres
>>> qui ont jeté l'éponge. Ça fait maintenant deux mois que je me tape
>>> de la relecture de code. Toutes les classes sont bien écrites, mais
>>> avec des héritages dans tous les sens et des surcharges du même
>>> tonneau. Au final, tu as vraiment du mal à voir qui fait quoi
>>> d'autant que le coup du 'virtual' en C++ est un truc
>>> particulièrement piégeux.
>> Ben non. Le virtuel n'est pas piégeux puisque ça veut juste dire que la
>> fonction est polymorphe, ce qui est le défaut en Smalltalk, par exemple.
>
> Et bien si, c'est piégeux. Parce que tu peux avoir une fonction
> start dans la classe mère qui fait un tas de choses nécessaire à
> l'objet en question.

En général, on fera cela dans le constructeur.


> Lorsque tu définis (ou que quelqu'un d'autre le
> fait) une fonction start surchargée dans une classe qui hérite de la
> première, c'est _piégeux_.

Surchargée ou surdéfinie (utilisation de l'overloading ou de
l'overwriting ?). Ce n'est pas la même chose.

> Des bourdes comme ça, j'en corrige des
> tas et tu serais bien le premier à ne jamais en avoir fait.

Ben non, c'est fait pour. Chaque classe doit faire ce qu'elle a à faire.
Je ne vois pas en quoi c'est "piégeux". C'est justement ça l'a
programmation objet, ou alors tu t'expliques mal et je ne comprends pas.
>
>>>
>>> Il y a des défauts dans le code, un tas de défaut de conception
>>> (variables d'instances qui ne sont pas dans la bonne classe)
>> S'il y a des attributs de classe qui ne sont pas dans la bonne classe,
>> cela veut dire que le principe de forte cohésion, qui sous-tend la
>> modularité objet, n'est pas respecté.
>
> Ça veut surtout dire que le type qui a codé la classe en question ne
> raisonne par de la même façon que le type qui la corrige. Rien de
> plus.

Non et non. Décidément tu n'as pas tout compris de l'objet. S'il y a des
attributs dans une classe qui ne devraient pas être là parce qu'ils ne
relèvent pas de l'abstraction qu'implémente la classe, c'est que la
conception est mal fichue et que le principe de forte cohésion n'est pas
respecté. Point-barre.
>
>>> ou défaut plus graves (entre autres fonctions virtuelles qui sont écrasées
>>> par celles de la classe fille,
>> Ca veut dire quoi "écrasée" ? surchargée avec une autre signature ? Je
>> ne comprends pas ce que tu veux dire.
>
> Ça veut dire surchargée, rien d'autre.

C'est ton vocabulaire qui montre que tu ne maîtrises pas bien l'objet
car on ne dit jamais "écrasée" mais surchargée ou surdéfinie (pour le
polymorphisme).
Tu sembles avoir appris l'objet "sur le tas". Ce n'est pas une tare, au
contraire c'est tout à fait respectable compte tenu de la complexité du
domaine lorsqu'on aborde de gros projets mais tu ne peux pas dire que tu
connais parfaitement l'objet (ni C++ d'ailleurs).
Pour ta gouverne personnelle sache que j'ai utilisé l'objet dès les
premiers articles de Grady Booch en 1983 et que j'enseigne C++ encore
(bien que je sois en retraite) pour des entreprises ainsi que la
conception objet et Java. A une époque (entre 1995 et 2005), je donnais
quasiment un cours de C++ tous les 6 semaines.
>
>>> mais il faut appeler récursivement toutes celles des parents), et je ne suis pas sûr, mais alors vraiment
>>> pas sûr que je prenne moins de temps à corriger le truc qu'à réécrire
>>> le code 'from scratch'. Et je ne parle que du côté compréhensible du
>>> code, pas encore de l'organisation des classes.
>> Visiblement la conception n'est pas bonne.
>
> Voilà. Dès qu'un truc devient complexe, la conception n'est pas la
> bonne. On change de conception, jamais de paradigme, ça demanderait
> trop de travail.

C'est une remarque qui n'a pas de sens. Si le projet est en objet, quand
on fait des modifications, on ne va pas repartir de zéro pour le recoder
en procédural...
Ca n'empêche pas de faire les choses correctement.
>
>>>> De plus
>>>> l'héritage (comme la composition) respecte les propriétés d'une relation
>>>> d'ordre stricte. Il n'y a jamais d'héritage "transversal" entre des
>>>> hiérarchies d'héritage différentes.
>>> Où ai-je prétendu le contraire ?
>> Tu disais "dans tous les sens" (ça inclus le transversal...)
>
> Sans commentaire.
>
>>>>> des templates en veux-tu-en-voilà,
>>>> Les templates servent à la réutilisabilté et l'héritage à la
>>>> factorisation. Ce n'est pas pareil. Les templates sont essentiels pour
>>>> ne pas dupliquer du code par copier/coller ce qui fabrique du code non
>>>> maintenable s'il y a un défaut dans le code dupliqué, comme je l'ai vu,
>>>> jusqu'à une dizaine d'exemplaires dans des fichiers différents.
>>> Certes, les templates, ça peut être pratique. Ça ne concourt
>>> généralement pas à la lisibilité du code.
>> Aujourd'hui l'utilisation des templates est incontournable, au moins
>
> Non.

C'est contournable mais ça donne du code moins réutilisable.
Préséance ???
Diable !
Qu'est-ce que cela peut vouloir dire ?
>
>>> sans se préocupper dans les détails de tout ce qui est affectation et
>>> libération de mémoire (un simple delete sur un
>>> objet vire toute la mémoire associée à cet objet.
>> Ben non justement. Pas s'il y a du polymorphisme avec allocation mémoire
>> dynamique à tous les étages de l'héritage. Il faut que les destructeurs
>> soient virtuels. On doit donc s'en préoccuper !
>
> Le programmeur, in fine, n'a pas à s'en préoccuper. Seul celui qui
> code la classe en question doit le savoir. L'intérêt du C++,
> c'est justement de cacher au programmeur de genre de choses.
> Voir des programmeurs utiliser la libcstd++ avec des listes, des maps et
> pleins d'autres choses et ne pas imaginer un instant la gestion
> mémoire qui est faite derrière me désole au plus haut point.

Là nous sommes d'accord. Un bon programmeur doit savoir.
J'insiste, un constructeur ne peut pas être virtuel. C'est écrit dans
tous les bouquins et même et surtout, dans la norme.

Peut-être parles-tu de l'idiome de constructeur de copie qui passe par
le clonage ?

JKB

unread,
Dec 3, 2011, 4:37:19 PM12/3/11
to
Le Sat, 03 Dec 2011 21:24:35 +0100,
Wykaaa <wyk...@yahoo.fr> écrivait :
> JKB a écrit :
>> Le Sat, 03 Dec 2011 13:54:44 +0100,
>> Wykaaa <wyk...@yahoo.fr> écrivait :
>>> JKB a écrit :
>>>> Mouais.
>>>>
>>>>> 3) encapsulation (qui participe au faible couplage)
>>>> Rien à voir avec un code objet. L'encapsulation se fait aussi en
>>>> Fortran77 qui n'est à ma connaissance pas objet pour un sou.
>>> L'encapsulation, au sens objet du terme, consiste à mettre
>>> systématiquement les attributs de classe dans la partie "private" et à
>>> coder des "getteurs" et des "setteurs" pour les accéder et modifier les
>>> valeurs. Ca n'a pas grand chose à voir avec la pseudo-encapsulation
>>> qu'on peut faire en Fortran77.
>>
>> C'est exactement ce qu'on peut faire à grands coups d'ENTRY en
>> Fortran.
>
> Non, pas exactement car le compilateur ne te dira rien si tu accèdes
> directement à certaines variables. Avec provate, tu es certain de ne
> pouvoir accéder aux attributs autrement que par des accesseurs ou
> modifieurs.

Si je t'écris un truc du genre :

subroutine TOTO()
implicit none
integer*4 M_A
integer*4 A
save A
return

entry GetA(A)
A = M_A
return

entry SetA(A)
M_A = A
return

end subroutine

je ne vois pas comment tu peux accéder à M_A sans passer par un
accesseur. C'est même à très peu de chose près équivalent à un
singleton du C++. La variable M_A est privée et le seul moyen de la
modifier est de passer par GetA() ou SetA().

>>>>> C'est justement l'ensemble de tous ces principes qui fait que l'on sait
>>>>> exactement où faire les modifications et détecter plus rapidement
>>>>> l'origine des défauts.
>>>> Non. Là, aujourd'hui, je bosse sur un code (plus exactement, je
>>>> passe après une équipe de developpeurs qui est partie) comportant
>>>> plusieurs milliers de classes avec du polymorphisme, des templates
>>>> et des tas de choses typiques du C++, de celles que les programmeurs
>>>> fous mettent partout pour se faire plaisir.
>>> Ce n'est pas pour se faire plaisir mais pour que le code soit de
>>> meilleure qualité. Je n'ai jamais vu un programmeur C++ débutant mettre
>>> des templates et faire du polymorphisme partout. C'est plutôt le
>>> contraire. Un débutant en C++ va avoir tendance à coder comme en C, ce
>>> qui est la pire des choses à faire en C++.
>>>
>>> En général, les programmeurs C++ n'utilisent pas toutes ces choses pour
>>> "se faire plaisir" mais par nécessité d'appliquer correctement l'objet
>>> et la réutilisation (la généricité existe dans des langages non objets
>>> comme ADA83). Quant au polymorphisme, il existe aussi dans des langages
>>> non objet comme ML ou Caml.
>>>
>>
>> Et ?
>
> Tu semblais "pester" contre le polymorphisme...

Oui. Et ?

>>
>>>> Personnellement, je suis freelance et je dois dire aussi que je passe après plusieurs autres
>>>> qui ont jeté l'éponge. Ça fait maintenant deux mois que je me tape
>>>> de la relecture de code. Toutes les classes sont bien écrites, mais
>>>> avec des héritages dans tous les sens et des surcharges du même
>>>> tonneau. Au final, tu as vraiment du mal à voir qui fait quoi
>>>> d'autant que le coup du 'virtual' en C++ est un truc
>>>> particulièrement piégeux.
>>> Ben non. Le virtuel n'est pas piégeux puisque ça veut juste dire que la
>>> fonction est polymorphe, ce qui est le défaut en Smalltalk, par exemple.
>>
>> Et bien si, c'est piégeux. Parce que tu peux avoir une fonction
>> start dans la classe mère qui fait un tas de choses nécessaire à
>> l'objet en question.
>
> En général, on fera cela dans le constructeur.

Non, pour une seule raison. Il est impossible de gérer proprement
les erreurs dans un constructeur (sauf à appeler un throw quelque
chose, mais ce n'est pas ce qui se fait de mieux lorsqu'il faut
traiter des erreurs d'I/O un peu tordues).

>> Lorsque tu définis (ou que quelqu'un d'autre le
>> fait) une fonction start surchargée dans une classe qui hérite de la
>> première, c'est _piégeux_.
>
> Surchargée ou surdéfinie (utilisation de l'overloading ou de
> l'overwriting ?). Ce n'est pas la même chose.
>
>> Des bourdes comme ça, j'en corrige des
>> tas et tu serais bien le premier à ne jamais en avoir fait.
>
> Ben non, c'est fait pour. Chaque classe doit faire ce qu'elle a à faire.
> Je ne vois pas en quoi c'est "piégeux". C'est justement ça l'a
> programmation objet, ou alors tu t'expliques mal et je ne comprends pas.

Je crois surtout que tu as des oeillères. Considères cinq classes
qui dérivent l'une de l'autre : A->B->C->D->E. Dans B, tu définis
une méthode configure(), virtuelle, qui s'occupe de B. Mais
potentiellement, tu peux la réécrire dans E. Le cas le plus courant
de bourde est l'absence de déclaration de cette fonction virtuelle
dans C et D (je ne suis pas allé voir dans les specs du C++, mais je
_sais_ que g++ n'appellera pas le configure() de E dans ce cas). Et
le plus problématique, c'est que si tu veux que la méthode configure()
dans E fasse tout ce que fait celle de B plus deux ou trois choses,
tu es contraint de l'appeler explicitement. Deuxième source de
problème parce qu'en cas de modification de l'héritage ou de la
hiérarchie par C ou D, le truc ne fonctionne plus. La plupart du
temps, les dévs recopient la méthode de B dans celle de E. Autre
source de pépin lorsque B change. Bref, l'objet, c'est très bien en
théorie. Dans la pratique, c'est vraiment autre chose.

Et je ne parle même pas d'autres trucs rigolos du C++ comme
l'effactement des vtables à l'appel du destructeur de la classe et
non en sortie d'icelle (ce qui serait vraiment plus logique).

>>>>
>>>> Il y a des défauts dans le code, un tas de défaut de conception
>>>> (variables d'instances qui ne sont pas dans la bonne classe)
>>> S'il y a des attributs de classe qui ne sont pas dans la bonne classe,
>>> cela veut dire que le principe de forte cohésion, qui sous-tend la
>>> modularité objet, n'est pas respecté.
>>
>> Ça veut surtout dire que le type qui a codé la classe en question ne
>> raisonne par de la même façon que le type qui la corrige. Rien de
>> plus.
>
> Non et non. Décidément tu n'as pas tout compris de l'objet. S'il y a des
> attributs dans une classe qui ne devraient pas être là parce qu'ils ne
> relèvent pas de l'abstraction qu'implémente la classe, c'est que la
> conception est mal fichue et que le principe de forte cohésion n'est pas
> respecté. Point-barre.

Encore une fois, j'ai parfaitement compris ce qu'est la
programmation orientée objet (sinon, je ferai autre chose comme
boulot). Seulement, avant de faire de l'objet, j'ai fait énormément
de procédural, ce qui me permet de comparer les deux. Dans la
théorie, tu as parfaitement raison. Dans la pratique, ton
raisonnement est biaisé. J'ai un exemple qui me vient à l'esprit
parce qu'il m'a posé pas mal de problèmes récemment. Une sombre
histoire de timout de pilotes de périphériques. La logique voudrait
qu'il soit associé à un périphérique. Sauf que la classe
périphérique en question hérite de tout un bazar de gestion des
pilotes et que le bazar en question est hérité par d'autres classes
(d'écriture de données) qui ont elles aussi un timeout. La logique
élémentaire voudrait que ce timeout soit une variable d'instance de
la classe pilote. Sauf qu'un tiers doit pouvoir écrire le plus
simplement du monde un pilote pour un nouveau matériel. Comme ce
timeout peut-être utilisé (avec une autre signification, tant qu'on
y est) par quelqu'un d'autre, il a été remonté de plusieurs classes
avec une initialisation par défaut. Il y a donc un fossé entre la
théorie et la pratique ! Là encore, je ne suis pas en train de dire
que c'est bien ou mal, que le principe de forte cohésion est
respecté ou non, juste de te signaler les codes que je vois tous les
jours contredisent tes assertions.

>>>> ou défaut plus graves (entre autres fonctions virtuelles qui sont écrasées
>>>> par celles de la classe fille,
>>> Ca veut dire quoi "écrasée" ? surchargée avec une autre signature ? Je
>>> ne comprends pas ce que tu veux dire.
>>
>> Ça veut dire surchargée, rien d'autre.
>
> C'est ton vocabulaire qui montre que tu ne maîtrises pas bien l'objet
> car on ne dit jamais "écrasée" mais surchargée ou surdéfinie (pour le
> polymorphisme).

Si tu veux ergoter sur les termes, on peut ergoter sur les termes.

> Tu sembles avoir appris l'objet "sur le tas". Ce n'est pas une tare, au
> contraire c'est tout à fait respectable compte tenu de la complexité du
> domaine lorsqu'on aborde de gros projets mais tu ne peux pas dire que tu
> connais parfaitement l'objet (ni C++ d'ailleurs).

Je n'ai jamais prétendu connaître le C++ sur le bout des doigts,
j'ai fait mes armes de POO en ADA.

> Pour ta gouverne personnelle sache que j'ai utilisé l'objet dès les
> premiers articles de Grady Booch en 1983 et que j'enseigne C++ encore
> (bien que je sois en retraite) pour des entreprises ainsi que la
> conception objet et Java. A une époque (entre 1995 et 2005), je donnais
> quasiment un cours de C++ tous les 6 semaines.

Tiens, un argument d'autorité. J'en suis fort aise. Je ne t'envoie pas
mon CV, ça ne servirait à rien, mais sache seulement que je fais _aussi_
dans l'enseignement (et dans la recherche sur le parallélisme,
enfin, des trucs sympas comme tout et où on n'aime effectivement pas
la POO pour tout un tas de bonnes raisons).

>>>> mais il faut appeler récursivement toutes celles des parents), et je ne suis pas sûr, mais alors vraiment
>>>> pas sûr que je prenne moins de temps à corriger le truc qu'à réécrire
>>>> le code 'from scratch'. Et je ne parle que du côté compréhensible du
>>>> code, pas encore de l'organisation des classes.
>>> Visiblement la conception n'est pas bonne.
>>
>> Voilà. Dès qu'un truc devient complexe, la conception n'est pas la
>> bonne. On change de conception, jamais de paradigme, ça demanderait
>> trop de travail.
>
> C'est une remarque qui n'a pas de sens. Si le projet est en objet, quand
> on fait des modifications, on ne va pas repartir de zéro pour le recoder
> en procédural...

Et bien si. Lorsque la modification d'un projet prend plus de temps
que le recodage 'from scratch' (cas vécu et pas qu'une fois), la logique
et l'économie veulent qu'on reparte de zéro.

<snip>

>> Cela n'engage que toi. L'application à laquelle je fais allusion est
>> un truc qui doit piloter des gazillons de périphériques différents
>> chez l'habitant. Au mieux, tu as une classe par pilote de
>> périphérique (et c'est vraiment au mieux) qui hérite de tout un tas
>> de choses. Actuellement, dans l'application, on a plus de 900 pilotes
>> différents.
>
> Ca n'empêche pas de faire les choses correctement.

Va jusqu'au bout de ton raisonnement. Ça pourrait devenir
intéressant.

<snip>

>>> Il faut des programmeurs ex-pé-ri-men-tés dans ces domaines (voir
>>> ci-dessus).
>>>> Maintenant, l'objet, c'est un paradigme qui fait que les procédures
>>>> procèdent des données et non le contraire comme dans les approches
>>>> fonctionnelles ou procédurales. Dit autrement, cela revient à
>>>> laisser tomber l'éternelle question de savoir à qui appartient telle
>>>> ou telle donnée
>>> Non justement car il faut respecter les principes une classe=une
>>> abstraction et la forte cohésion interne de chaque classe (tu as fait
>>> "mouais" à tous ces principes qui sont fondamentaux en approche objet.
>>> Si on ne les respecte pas strictement alors on ne fait pas de l'objet
>>> mais des immondices dans lesquels tu sembles être tombé involontairement :-)
>>
>> La réponse est à côté de la plaque. Je ne suis pas en train de
>> parler d'abstraction mais de préseance.
>
> Préséance ???
> Diable !
> Qu'est-ce que cela peut vouloir dire ?

Exactement ce que j'ai écrit quinze lignes plus haut, certes un peu
différemment.

<snip>

>>>> Je ne parle pas de _constructeur_, mais de _constructeur de copie_.
>>>> Je sais parfaitement qu'un constructeur ne peut pas être virtuel et
>>>> qu'il est de bon ton que le destructeur le soit.
>>> Le constructeur de copie est, avant tout,un constructeur et, à ce titre,
>>> il ne peut être virtuel...
>>
>> Je vais donc dire ça à mon compilo C++. Il ne semble pas le savoir.
>> Je fais ça pour interdire que le truc décide de faire une copie dans
>> mon dos (ou que je rate une opération de copie). Je le déclare même
>> d'office purement virtuel.
>
> J'insiste, un constructeur ne peut pas être virtuel. C'est écrit dans
> tous les bouquins et même et surtout, dans la norme.
>
> Peut-être parles-tu de l'idiome de constructeur de copie qui passe par
> le clonage ?

Non, je parle de 'construteur de copie' qui est la traduction
française de ce que j'ai dans mon bouquin de référence C++ qui est
tout en américain et actuellement sur mon bureau à vingt bornes
d'ici.

Fin de la discussion parce qu'on n'avancera pas.

Pascal J. Bourguignon

unread,
Dec 3, 2011, 5:06:13 PM12/3/11
to
JKB <j...@koenigsberg.invalid> writes:

> Je crois surtout que tu as des oeillères. Considères cinq classes
> qui dérivent l'une de l'autre : A->B->C->D->E. Dans B, tu définis
> une méthode configure(), virtuelle, qui s'occupe de B. Mais
> potentiellement, tu peux la réécrire dans E. Le cas le plus courant
> de bourde est l'absence de déclaration de cette fonction virtuelle
> dans C et D (je ne suis pas allé voir dans les specs du C++, mais je
> _sais_ que g++ n'appellera pas le configure() de E dans ce cas). Et
> le plus problématique, c'est que si tu veux que la méthode configure()
> dans E fasse tout ce que fait celle de B plus deux ou trois choses,
> tu es contraint de l'appeler explicitement. Deuxième source de
> problème parce qu'en cas de modification de l'héritage ou de la
> hiérarchie par C ou D, le truc ne fonctionne plus. La plupart du
> temps, les dévs recopient la méthode de B dans celle de E. Autre
> source de pépin lorsque B change. Bref, l'objet, c'est très bien en
> théorie. Dans la pratique, c'est vraiment autre chose.

C'est un problème de C++, pas de la programmation par objets.
Ce genre de problème n'existe pas dans les vrai langages de
programmation objet (Smalltalk, Eiffel, Lisp, Objective-C, etc).


> Et je ne parle même pas d'autres trucs rigolos du C++ comme
> l'effactement des vtables à l'appel du destructeur de la classe et
> non en sortie d'icelle (ce qui serait vraiment plus logique).

Oui, ce n'est pas le seul problème de C++...


--
__Pascal Bourguignon__ http://www.informatimago.com/
A bad day in () is better than a good day in {}.

lionmarron

unread,
Dec 4, 2011, 3:10:06 PM12/4/11
to
Le 26/11/2011 11:23, Bertrand Lenoir-Welter a écrit :
>
> De toute façon, in fine, c'est du procédural.

J'aurais difficilement pu intervenir dans la discussion de spécialistes
qui précède (celle ayant suivi le message de Bertrand), mais il me
semble que, dans un contexte où elle ne s'impose pas, l'approche objet
revient peut-être à utiliser un marteau pilon pour écraser une mouche.

Personnellement il me faudra sans doute comprendre cette méthode
d'approche, parce que je souhaiterais échanger des morceaux de
programmes avec d'autres, ou plutôt copier sur eux (c'est plus
réaliste), et que c'est une méthode qui semble assez employée (notamment
en Python). Mais j'ignore si cela servira à quelque chose de plus dans
le cadre que ce que je peux faire (autrement dit cela ne prouvera pas
que cette méthode soit réellement utile).

De la même façon je parlerais verlan si j'habitais dans un endroit où
tout le monde parle en verlan plutôt qu'en français, ce qui ne
prouverait pas que le verlan soit supérieur au français.

--
lionmarron

Bertrand Lenoir-Welter

unread,
Dec 5, 2011, 3:41:37 AM12/5/11
to
> il me semble que, dans un contexte où elle ne s'impose pas,
> l'approche objet revient peut-être à utiliser un marteau
> pilon pour écraser une mouche.

Non, l'approche objet est avant tout une vue de l'esprit. Il est inutile
de faire une classe pour un programme qui fait "Hello World", mais dès
que ça devient un peu plus gros et qu'on a besoin de compartimenter le
code, l'approche objet devient une option intéressante - pas forcément
incontournable mais intéressante.

Maintenant, les langages de programmation sont aussi imparfaits que les
programmeurs. Je suis plutôt en phase avec les problèmes soulevés par
JKB - pour une fois qu'il y a un troll techniquement intéressant - mais
il ne faudrait pas non plus jeter le bébé avec l'eau du bain.

lionmarron

unread,
Dec 5, 2011, 4:57:56 PM12/5/11
to
D'accord.

--
lionmarron



Rémi Moyen

unread,
Dec 10, 2011, 12:20:31 PM12/10/11
to
On va me dire que ça serait sans doute plus à sa place sur le groupe de
C++, mais puisque ces questions arrivent dans cette discussion, j'y reste...

En lisant ces échanges, je vois plusieurs points qui ne me semblent pas
clair. Je ne prétends absolument pas maîtriser le C++ ni n'importe quel
autre langage, ce sont des vraies questions innocentes :

Le 03/12/2011 21:37, JKB a écrit :

> Je crois surtout que tu as des oeillères. Considères cinq classes
> qui dérivent l'une de l'autre : A->B->C->D->E. Dans B, tu définis
> une méthode configure(), virtuelle, qui s'occupe de B. Mais
> potentiellement, tu peux la réécrire dans E. Le cas le plus courant
> de bourde est l'absence de déclaration de cette fonction virtuelle
> dans C et D (je ne suis pas allé voir dans les specs du C++, mais je
> _sais_ que g++ n'appellera pas le configure() de E dans ce cas).

Je ne vois pas du tout pourquoi il est nécessaire de redéclarer la
fonction dans C et D. Pour autant que je puisse voir, appeler
configure() sur un objet dont le type "réel" est E appelle bien
E::configure(), même si le type statique de l'objet est C ou D et que
configure() n'est déclarée que dans B et E ?

> le plus problématique, c'est que si tu veux que la méthode configure()
> dans E fasse tout ce que fait celle de B plus deux ou trois choses,
> tu es contraint de l'appeler explicitement. Deuxième source de
> problème parce qu'en cas de modification de l'héritage ou de la
> hiérarchie par C ou D, le truc ne fonctionne plus. La plupart du
> temps, les dévs recopient la méthode de B dans celle de E. Autre
> source de pépin lorsque B change.

Pour ma part, je vois plus souvent E::configure() commencer par appeler
D::configure() (même si celle-ci n'est pas déclarée, que seul
B::configure() existe), ce qui limite les dégâts que tu évoques et a
l'air de marcher. Mais je suis d'accord que ça n'est pas idéal.

>> J'insiste, un constructeur ne peut pas être virtuel. C'est écrit dans
>> tous les bouquins et même et surtout, dans la norme.
>>
>> Peut-être parles-tu de l'idiome de constructeur de copie qui passe par
>> le clonage ?
>
> Non, je parle de 'construteur de copie' qui est la traduction
> française de ce que j'ai dans mon bouquin de référence C++ qui est
> tout en américain et actuellement sur mon bureau à vingt bornes
> d'ici.

Là, j'avoue que je suis perdu. Je ne fréquente pas beaucoup de bouquins
techniques en français, mais il me semble bien que le "constructeur de
copie", c'est la même chose que le "copy constructor", i.e. "A::A(const
A&)". Si c'est bien ça, je suis sincèrement curieux de savoir en quoi il
peut être virtuel ? Sinon, je suis aussi sincèrement curieux de savoir
de quoi tu parles...

Merci !
--
Rémi Moyen

Wykaaa

unread,
Dec 11, 2011, 7:10:52 PM12/11/11
to
Le 10/12/11 18:20, Rémi Moyen a écrit :
Voilà. Tu as raison.

>>> J'insiste, un constructeur ne peut pas être virtuel. C'est écrit dans
>>> tous les bouquins et même et surtout, dans la norme.
>>>
>>> Peut-être parles-tu de l'idiome de constructeur de copie qui passe par
>>> le clonage ?
>>
>> Non, je parle de 'construteur de copie' qui est la traduction
>> française de ce que j'ai dans mon bouquin de référence C++ qui est
>> tout en américain et actuellement sur mon bureau à vingt bornes
>> d'ici.
>
> Là, j'avoue que je suis perdu. Je ne fréquente pas beaucoup de bouquins
> techniques en français, mais il me semble bien que le "constructeur de
> copie", c'est la même chose que le "copy constructor", i.e. "A::A(const
> A&)". Si c'est bien ça, je suis sincèrement curieux de savoir en quoi il
> peut être virtuel ? Sinon, je suis aussi sincèrement curieux de savoir
> de quoi tu parles...
>
> Merci !

Personnellement, j'ai cessé de lui répondre car il a dit quelques
énormités comme celle-ci sur les constructeurs. Le constructeur de copie
(copy constructor) est un constructeur comme un autre qui ne peut pas
être virtualisé. C'est pour cette raison qu'a été élaboré l'idiome de
constructeur de copie qui passe par le clonage.
Si son bouquin dit le contraire, il est urgent de le mettre à la poubelle.

JKB

unread,
Dec 12, 2011, 5:46:18 AM12/12/11
to
Le Mon, 12 Dec 2011 01:10:52 +0100,
Wykaaa <wyk...@yahoo.fr> écrivait :
>
> Personnellement, j'ai cessé de lui répondre car il a dit quelques
> énormités comme celle-ci sur les constructeurs. Le constructeur de copie
> (copy constructor) est un constructeur comme un autre qui ne peut pas
> être virtualisé. C'est pour cette raison qu'a été élaboré l'idiome de
> constructeur de copie qui passe par le clonage.
> Si son bouquin dit le contraire, il est urgent de le mettre à la poubelle.
>

Voilà, mon bouquin ne pense pas comme toi, donc il est bon à mettre
à la poubelle. Personnellement, j'ai arrêté de te répondre parce que
je n'ai pas que cela à faire et que je l'ai écrit.

Au passage, tu nous expliqueras comment tu appelles les choses
suivantes :

private:
toto(const toto &orig);
toto& operator=(const const toto &orig);
// Naturellement sans les fonctions correspondantes. Et ça marche
// encore avec un virtual = 0 sur certains compilos.

Dans mon bouquin-à-moi-qui-est-mauvais-et-que-je-dois-jeter, ces
deux trucs sont appelés des constructeurs de copie (à la traduction
près). Tu vas certainement nous indiquer un bouquin dans lequel ces
deux trucs sont appelés d'une manière différente, personnellement,
je n'en ai cure puisque ces deux trucs font exactement (et
implicitement s'ils ne sont pas déclarés) une copie de l'objet. Et
j'enfonce le clou, dans mon bouquin Java, il y a exactement la même
chose.

<EOT>

Wykaaa

unread,
Dec 12, 2011, 6:20:56 AM12/12/11
to
Le 12/12/11 11:46, JKB a écrit :
> Le Mon, 12 Dec 2011 01:10:52 +0100,
> Wykaaa<wyk...@yahoo.fr> écrivait :
>>
>> Personnellement, j'ai cessé de lui répondre car il a dit quelques
>> énormités comme celle-ci sur les constructeurs. Le constructeur de copie
>> (copy constructor) est un constructeur comme un autre qui ne peut pas
>> être virtualisé. C'est pour cette raison qu'a été élaboré l'idiome de
>> constructeur de copie qui passe par le clonage.
>> Si son bouquin dit le contraire, il est urgent de le mettre à la poubelle.
>>
>
> Voilà, mon bouquin ne pense pas comme toi, donc il est bon à mettre
> à la poubelle. Personnellement, j'ai arrêté de te répondre parce que
> je n'ai pas que cela à faire et que je l'ai écrit.
>
> Au passage, tu nous expliqueras comment tu appelles les choses
> suivantes :
>
> private:
> toto(const toto&orig);
> toto& operator=(const const toto&orig);
> // Naturellement sans les fonctions correspondantes. Et ça marche
> // encore avec un virtual = 0 sur certains compilos.

Le premier est bien un constructeur de copie mais le second est la
surcharge de l'opérateur d'affectation qui n'a rien à voir avec un
constructeur. Il n'est pas héritable d'ailleurs...

Ôte-moi d'un doute. J'espère que tu ne considère pas que
toto& operator=(const const toto&orig);
est appelé quand on fait :
toto t1;
toto t2 = t1; // c'est le constructeur de copie qui est appelé ici !

Tu dis que "ça marche" (fonctionne plutôt) sur certains compilos (mais
pas tous apparemment). Sur lesquels cela "marche-t-il" ?

Et si tu mets virtual=0 sur ton constructeur de copie (ce qui est
impossible, encore une fois), tu vas l'appeler comment dans la classe
héritée (qui ne s'appellera pas toto) ?
Et à quoi ça servirait d'avoir un constructeur de copie virtuel dans une
classe puisqu'on ne pourrait pas en faire d'instance ?

J'ai fait l'essai avec Xcode (sur Mac), il râle dès que je déclare un
constructeur virtuel (de copie ou non).
>
> Dans mon bouquin-à-moi-qui-est-mauvais-et-que-je-dois-jeter, ces
> deux trucs sont appelés des constructeurs de copie (à la traduction
> près). Tu vas certainement nous indiquer un bouquin dans lequel ces
> deux trucs sont appelés d'une manière différente, personnellement,
> je n'en ai cure puisque ces deux trucs font exactement (et
> implicitement s'ils ne sont pas déclarés) une copie de l'objet. Et
> j'enfonce le clou, dans mon bouquin Java, il y a exactement la même
> chose.

Quand il n'y a pas de constructeur de copie déclaré, il y en a un
(implicite) qui est appelé et qui fait ce qu'on appelle une "bitwise
copy" (copie bit à bit). Ce n'est évidemment pas ce que l'on veut s'il y
a des pointeurs dans les attributs de la classe (dans ce cas on veut
recopier ce qui est "au bout" des pointeurs).

La notion de virtuel pur n'existe pas en Java !!

Wykaaa

JKB

unread,
Dec 12, 2011, 7:03:20 AM12/12/11
to
Le Mon, 12 Dec 2011 12:20:56 +0100,
Wykaaa <wyk...@yahoo.fr> écrivait :
Je n'ai jamais prétendu le contraire. Relis bien tous les mots du
thread depuis le début et surtout sans en sauter un seul.

Paul Gaborit

unread,
Dec 12, 2011, 7:44:05 AM12/12/11
to

À (at) Mon, 12 Dec 2011 12:20:56 +0100,
Wykaaa <wyk...@yahoo.fr> écrivait (wrote):

> Quand il n'y a pas de constructeur de copie déclaré, il y en a un
> (implicite) qui est appelé et qui fait ce qu'on appelle une "bitwise
> copy" (copie bit à bit). Ce n'est évidemment pas ce que l'on veut s'il
> y a des pointeurs dans les attributs de la classe (dans ce cas on veut
> recopier ce qui est "au bout" des pointeurs).

Une bonne pratique du C++ consiste d'ailleurs à *toujours* déclarer le
copy-constructor quitte à ne pas le définir.

Cela évite de se retrouver accidentellement avec un copy-constructor
créé par défaut qui a peu de chance de faire exactement ce qu'il faut.

Cela fait partie des nombreux piège du C++.

--
Paul Gaborit - <http://perso.mines-albi.fr/~gaborit/>

JKB

unread,
Dec 12, 2011, 2:32:26 PM12/12/11
to
Le Mon, 12 Dec 2011 13:44:05 +0100,
Paul Gaborit <Paul.G...@invalid.invalid> écrivait :
Nous sommes parfaitement d'accord. Tu prêches à un convaincu...

Paul Gaborit

unread,
Dec 13, 2011, 3:39:26 AM12/13/11
to

À (at) Mon, 12 Dec 2011 19:32:26 +0000 (UTC),
JKB <j...@koenigsberg.invalid> écrivait (wrote):

> Le Mon, 12 Dec 2011 13:44:05 +0100,
> Paul Gaborit <Paul.G...@invalid.invalid> écrivait :
>>
>> À (at) Mon, 12 Dec 2011 12:20:56 +0100,
>> Wykaaa <wyk...@yahoo.fr> écrivait (wrote):
>>
>>> Quand il n'y a pas de constructeur de copie déclaré, il y en a un
>>> (implicite) qui est appelé et qui fait ce qu'on appelle une "bitwise
>>> copy" (copie bit à bit). Ce n'est évidemment pas ce que l'on veut s'il
>>> y a des pointeurs dans les attributs de la classe (dans ce cas on veut
>>> recopier ce qui est "au bout" des pointeurs).
>>
>> Une bonne pratique du C++ consiste d'ailleurs à *toujours* déclarer le
>> copy-constructor quitte à ne pas le définir.
>>
>> Cela évite de se retrouver accidentellement avec un copy-constructor
>> créé par défaut qui a peu de chance de faire exactement ce qu'il faut.
>>
>> Cela fait partie des nombreux piège du C++.
>
> Nous sommes parfaitement d'accord. Tu prêches à un convaincu...

Dans ce cas, nous serons d'accord pour dire que le C++ est un langage
qui regorge de tels pièges et qui n'est donc réellement utilisable que
par des développeurs expérimentés (comprenant parfaitement les dessous
du langage et ayant de bonnes pratiques bien établies).

Mais cet aspect "piègeux" est une caractéristique du C++ pas de la
programmation orientée objet dans son ensemble.

Bertrand Lenoir-Welter

unread,
Dec 13, 2011, 4:35:19 AM12/13/11
to
Tiens, je vais nourrir le troll en divergeant un peu. Désolé de le faire
ici plutôt que dans le forum C++ auquel je ne suis pas abonné, mais
comme l'endroit est calme, ça ne devrait pas trop déranger.

Ma question concerne les constructeurs de copie, dont je ne me suis
jusqu'à présent jamais servi. La plupart des classes pour lesquelles
j'ai besoin de copier les données d'une instance dans un autre forment
des listes chaînées, souvent avec des pointeurs sur des blocs de données
annexes.

Dans la plupart de ces classes, je code une fonction de copie qui
transférera les donnée de l'instance A vers l'instance B, à l'exception
des pointeurs. Si j'ai bien compris le fonctionnement d'un constructeur
de copie, celui-ci permet de créer B en initialisant ses données
internes avec le contenu de A, pointeurs compris, ce que je fais chez
moi avec B=new MyClass(); B->Copy(A); dans laquelle je fais la copie en
laissant les pointeurs de côté.

Je ne vois pas trop le côté indispensable du constructeur de copie.
L'avantage d'une fonction de copie maison est qu'on peut copier A dans
un B déjà alloué, ce qui m'arrive fréquemment.

Merci de m'éclairer sur l'utilité des constructeurs de copie (pas
seulement en C++, j'essaie de sauver la légitimité de ce message sur ce
groupe), utilité que je ne saisis pas a priori.

Avant de me faire tomber dessus par quelques fondamentalistes, je
précise que je code au quotidien en C++ (appris sur le tas à partir du
C), mais comme je ne travaille pas en équipe, j'ai sans doute une vision
pas très académique du langage, en plus de mauvaises habitudes.

Wykaaa

unread,
Dec 13, 2011, 1:01:33 PM12/13/11
to
Paul Gaborit a écrit :
En C++11, on pourra écrire :
struct NoCopy
{
NoCopy & operator =( const NoCopy & ) = delete;
NoCopy ( const NoCopy & ) = delete;
};

Ceci signifie qu'on ne veut ni de l'opérateur d'affectation, ni du
constructeur de copie par défaut.

Olivier Miakinen

unread,
Dec 14, 2011, 6:13:42 PM12/14/11
to
Le 13/12/2011 19:01, Wykaaa a écrit :
>>
> En C++11, on pourra écrire :
> struct NoCopy
> {
> NoCopy & operator =( const NoCopy & ) = delete;
> NoCopy ( const NoCopy & ) = delete;
> };
>
> Ceci signifie qu'on ne veut ni de l'opérateur d'affectation, ni du
> constructeur de copie par défaut.

Sympa !
0 new messages