Comment fais-tu alors pour faire de la conception ?
|> Qu'est-ce que tu appelles la sémantique d'un objet?
La sémantique d'un objet est l'ensemble de son comportement, qui doit
être déterminé par le rôle de l'objet dans l'application. Un
des aspects de la sémantique à considérer est la distinction
entre une sémantique de valeur et une sémantique de
référence. En gros, on utilise une sémantique de valeur quand
le rôle de l'objet est de réprésenter simplement une valeur
(numérique, chaîne de caractères, etc.) On utilise une
sémantique de référence quand l'identité de l'objet est
importante ; quand une copie n'en ferait pas l'affaire.
C'est évidemment une simplification radicale, mais à titre
d'exemple, considère un virement bancaire qui crédite ton compte
de 100 Euros. Les 100 Euros, c'est une valeur -- qu'on s'en sert de
l'original, ou d'une copie, 100 Euros, c'est 100 Euros. En revanche,
j'imagine que ça ne te plairait pas particulièrement si à la
place de le créditer à ton compte, on l'en créditait à une
copie, qui sera détruite à la fin de l'opération.
Et comme j'ai dit, c'est une simplification. On pourrait très bien
imaginer une application où on faisait une copie des comptes, aussi,
afin de pouvoir gérer des transactions (roll-back en cas d'erreur,
etc.)
En gros, un type qui a une sémantique de valeur supportera la copie
et l'affectation, au moyen d'un constructeur de copie et un opérateur
d'affectation publics (éventuellement fournis par le compilateur) ;
un type qui a une sémantique de référence interdira la copie et
l'affectation, en declarant le constructeur de copie et l'opérateur
d'affectation privés. Dans ce cas-là, il faut que le programmeur
les déclarent, parce que ceux fournis par le compilateur sont
toujours publics. (Il existe aussi des moyens d'interdire au
compilateur de générer les défauts, boost::noncopiable, par exemple.
Au moins d'être dans une position de largement diffuser l'idiome,
comme c'est le cas de Boost, ces moyens rélèvent de l'offuscation.)
[...]
|> Donc il me faut utiliser les pointeurs intelligents de Boost, ça
|> posera pas de problème??
Moins de problèmes. Peut-être. Disons qu'ils ont l'avantage
d'être déjà implémentés, y compris dans les contextes
multi-thread. Mais ils ne résoudent pas le problème des
références cycliques -- ils fournissent bien des outils pour
permettre à résoudre, mais il reste à toi de reconnaître le
problème et d'utiliser les outils à bon échéance. (Dans la
pratique, je n'ai pas vu beaucoup de cas où leur outil --
boost::weak_ptr, avait des avantages sur un pointeur bruts. Sinon que
le fait même de l'utiliser montre au lecteur que tu as considéré
le problème.) Et si Boost offre en fait les deux implémentations
classiques, c'est toujours à toi de choisir laquelle des deux
convient, et de faire attention à en respecter les limites.
Si tu n'as pas le problème des threads, tu pourrais aussi jeter un
coup d'oeil au GB_RefCntPtr chez moi. C'est beaucoup plus simple que
Boost (parce qu'il prétend en faire moins).
Comment fais-tu alors pour faire de la conception ?
|> Qu'est-ce que tu appelles la sémantique d'un objet?
La sémantique d'un objet est l'ensemble de son comportement, qui doit
être déterminé par le rôle de l'objet dans l'application. Un
des aspects de la sémantique à considérer est la distinction
entre une sémantique de valeur et une sémantique de
référence. En gros, on utilise une sémantique de valeur quand
le rôle de l'objet est de réprésenter simplement une valeur
(numérique, chaîne de caractères, etc.) On utilise une
sémantique de référence quand l'identité de l'objet est
importante ; quand une copie n'en ferait pas l'affaire.
C'est évidemment une simplification radicale, mais à titre
d'exemple, considère un virement bancaire qui crédite ton compte
de 100 Euros. Les 100 Euros, c'est une valeur -- qu'on s'en sert de
l'original, ou d'une copie, 100 Euros, c'est 100 Euros. En revanche,
j'imagine que ça ne te plairait pas particulièrement si à la
place de le créditer à ton compte, on l'en créditait à une
copie, qui sera détruite à la fin de l'opération.
Et comme j'ai dit, c'est une simplification. On pourrait très bien
imaginer une application où on faisait une copie des comptes, aussi,
afin de pouvoir gérer des transactions (roll-back en cas d'erreur,
etc.)
En gros, un type qui a une sémantique de valeur supportera la copie
et l'affectation, au moyen d'un constructeur de copie et un opérateur
d'affectation publics (éventuellement fournis par le compilateur) ;
un type qui a une sémantique de référence interdira la copie et
l'affectation, en declarant le constructeur de copie et l'opérateur
d'affectation privés. Dans ce cas-là, il faut que le programmeur
les déclarent, parce que ceux fournis par le compilateur sont
toujours publics. (Il existe aussi des moyens d'interdire au
compilateur de générer les défauts, boost::noncopiable, par exemple.
Au moins d'être dans une position de largement diffuser l'idiome,
comme c'est le cas de Boost, ces moyens rélèvent de l'offuscation.)
[...]
|> Donc il me faut utiliser les pointeurs intelligents de Boost, ça
|> posera pas de problème??
Moins de problèmes. Peut-être. Disons qu'ils ont l'avantage
d'être déjà implémentés, y compris dans les contextes
multi-thread. Mais ils ne résoudent pas le problème des
références cycliques -- ils fournissent bien des outils pour
permettre à résoudre, mais il reste à toi de reconnaître le
problème et d'utiliser les outils à bon échéance. (Dans la
pratique, je n'ai pas vu beaucoup de cas où leur outil --
boost::weak_ptr, avait des avantages sur un pointeur bruts. Sinon que
le fait même de l'utiliser montre au lecteur que tu as considéré
le problème.) Et si Boost offre en fait les deux implémentations
classiques, c'est toujours à toi de choisir laquelle des deux
convient, et de faire attention à en respecter les limites.
Si tu n'as pas le problème des threads, tu pourrais aussi jeter un
coup d'oeil au GB_RefCntPtr chez moi. C'est beaucoup plus simple que
Boost (parce qu'il prétend en faire moins).
Comment fais-tu alors pour faire de la conception ?
|> Qu'est-ce que tu appelles la sémantique d'un objet?
La sémantique d'un objet est l'ensemble de son comportement, qui doit
être déterminé par le rôle de l'objet dans l'application. Un
des aspects de la sémantique à considérer est la distinction
entre une sémantique de valeur et une sémantique de
référence. En gros, on utilise une sémantique de valeur quand
le rôle de l'objet est de réprésenter simplement une valeur
(numérique, chaîne de caractères, etc.) On utilise une
sémantique de référence quand l'identité de l'objet est
importante ; quand une copie n'en ferait pas l'affaire.
C'est évidemment une simplification radicale, mais à titre
d'exemple, considère un virement bancaire qui crédite ton compte
de 100 Euros. Les 100 Euros, c'est une valeur -- qu'on s'en sert de
l'original, ou d'une copie, 100 Euros, c'est 100 Euros. En revanche,
j'imagine que ça ne te plairait pas particulièrement si à la
place de le créditer à ton compte, on l'en créditait à une
copie, qui sera détruite à la fin de l'opération.
Et comme j'ai dit, c'est une simplification. On pourrait très bien
imaginer une application où on faisait une copie des comptes, aussi,
afin de pouvoir gérer des transactions (roll-back en cas d'erreur,
etc.)
En gros, un type qui a une sémantique de valeur supportera la copie
et l'affectation, au moyen d'un constructeur de copie et un opérateur
d'affectation publics (éventuellement fournis par le compilateur) ;
un type qui a une sémantique de référence interdira la copie et
l'affectation, en declarant le constructeur de copie et l'opérateur
d'affectation privés. Dans ce cas-là, il faut que le programmeur
les déclarent, parce que ceux fournis par le compilateur sont
toujours publics. (Il existe aussi des moyens d'interdire au
compilateur de générer les défauts, boost::noncopiable, par exemple.
Au moins d'être dans une position de largement diffuser l'idiome,
comme c'est le cas de Boost, ces moyens rélèvent de l'offuscation.)
[...]
|> Donc il me faut utiliser les pointeurs intelligents de Boost, ça
|> posera pas de problème??
Moins de problèmes. Peut-être. Disons qu'ils ont l'avantage
d'être déjà implémentés, y compris dans les contextes
multi-thread. Mais ils ne résoudent pas le problème des
références cycliques -- ils fournissent bien des outils pour
permettre à résoudre, mais il reste à toi de reconnaître le
problème et d'utiliser les outils à bon échéance. (Dans la
pratique, je n'ai pas vu beaucoup de cas où leur outil --
boost::weak_ptr, avait des avantages sur un pointeur bruts. Sinon que
le fait même de l'utiliser montre au lecteur que tu as considéré
le problème.) Et si Boost offre en fait les deux implémentations
classiques, c'est toujours à toi de choisir laquelle des deux
convient, et de faire attention à en respecter les limites.
Si tu n'as pas le problème des threads, tu pourrais aussi jeter un
coup d'oeil au GB_RefCntPtr chez moi. C'est beaucoup plus simple que
Boost (parce qu'il prétend en faire moins).
Moi aussi, je me suis formé sur le tas. (Je n'ai pas le niveau bac,
et je n'ai jamais suivi un cour d'informatique.)
Mais c'est un peu pour ça que j'insiste. Typiquement (en supposant
que mon expérience est typique), quand on apprend sur le tas, on
apprend surtout les détails. Or, pour maîtriser l'informatique, il
faut savoir commencer par la conception générale.
Je ne sais pas vraiment ce qu'il faudrait te conseiller. Moi, j'ai
toujours eu de la chance d'avoir un bon collègue au bon moment, pour
me diriger dans la bonne direction. Donc, on m'a conseillé le Booch
(_Object_ _Oriented_ _Design_ _with_ _Applications_, de Grady Booch,
ISBN 0-8053-0091-0), mais j'ai appris beaucoup plus en discussions
avec les collègues de l'époque. Enfin, le seul livre que je connais
qui traite vraiment le développement d'un programme complet en C++,
c'est _Designing_ _Object_ _Oriented_ _C++_ _Applications_ _Using_
_the_ _Booch_ _Method_, de Robert Martin (ISBN 0-13-203837-4). Il est
malheureusement un peu périmé -- notation Booch à la place de
USL, un C++ d'il y a dix ans. Mais à mon avis, ça vaut toujours la
peine.
Moi aussi, je me suis formé sur le tas. (Je n'ai pas le niveau bac,
et je n'ai jamais suivi un cour d'informatique.)
Mais c'est un peu pour ça que j'insiste. Typiquement (en supposant
que mon expérience est typique), quand on apprend sur le tas, on
apprend surtout les détails. Or, pour maîtriser l'informatique, il
faut savoir commencer par la conception générale.
Je ne sais pas vraiment ce qu'il faudrait te conseiller. Moi, j'ai
toujours eu de la chance d'avoir un bon collègue au bon moment, pour
me diriger dans la bonne direction. Donc, on m'a conseillé le Booch
(_Object_ _Oriented_ _Design_ _with_ _Applications_, de Grady Booch,
ISBN 0-8053-0091-0), mais j'ai appris beaucoup plus en discussions
avec les collègues de l'époque. Enfin, le seul livre que je connais
qui traite vraiment le développement d'un programme complet en C++,
c'est _Designing_ _Object_ _Oriented_ _C++_ _Applications_ _Using_
_the_ _Booch_ _Method_, de Robert Martin (ISBN 0-13-203837-4). Il est
malheureusement un peu périmé -- notation Booch à la place de
USL, un C++ d'il y a dix ans. Mais à mon avis, ça vaut toujours la
peine.
Moi aussi, je me suis formé sur le tas. (Je n'ai pas le niveau bac,
et je n'ai jamais suivi un cour d'informatique.)
Mais c'est un peu pour ça que j'insiste. Typiquement (en supposant
que mon expérience est typique), quand on apprend sur le tas, on
apprend surtout les détails. Or, pour maîtriser l'informatique, il
faut savoir commencer par la conception générale.
Je ne sais pas vraiment ce qu'il faudrait te conseiller. Moi, j'ai
toujours eu de la chance d'avoir un bon collègue au bon moment, pour
me diriger dans la bonne direction. Donc, on m'a conseillé le Booch
(_Object_ _Oriented_ _Design_ _with_ _Applications_, de Grady Booch,
ISBN 0-8053-0091-0), mais j'ai appris beaucoup plus en discussions
avec les collègues de l'époque. Enfin, le seul livre que je connais
qui traite vraiment le développement d'un programme complet en C++,
c'est _Designing_ _Object_ _Oriented_ _C++_ _Applications_ _Using_
_the_ _Booch_ _Method_, de Robert Martin (ISBN 0-13-203837-4). Il est
malheureusement un peu périmé -- notation Booch à la place de
USL, un C++ d'il y a dix ans. Mais à mon avis, ça vaut toujours la
peine.
"Christophe Lephay" writes:La notion de valeur a-t-elle une quelconque signification pour tes
objets ?
Je dirais que la clé, c'est prèsque l'inverse : si l'identité a
de l'importance pour l'objet, il faut lui donner une sémantique de
référence. Sinon, une sémantique de valeur (au moins qu'il y a
d'autres contraints, comme le polymorphisme).
En général, les objets avec une sémantique de valeur
offrent moins de contraintes et sont donc plus faciles à
utiliser.
Et c'est là où je me sépare de toi. Il n'y a pas un qui offre
moins de contraintes et qui est plus facile à utiliser.
...
Ce dont il faut bien se rendre compte, quand même, c'est que chaque
langage a ces propres idiomes, plus ou moins consacré, pour
implémenter ces deux sémantiques. Et que l'idiome de valeur en
C++, c'est bien la copie (profonde) de l'objet, et non le pointeur.
Typiquement, c'est même très rare qu'on soit amené à allouer
dynamiquement un objet à sémantique de valeur.
(L'implémentation des objets à sémantique de valeur peut
très bien utiliser la mémoire dynamique, quand par exemple la
taille ou la structure de l'objet peut varier dynamiquement. Mais à
ce moment-là, c'est un détail de l'implémentation de l'objet.)
"Christophe Lephay" <christophe-lephay@wanadoo.fr> writes:
La notion de valeur a-t-elle une quelconque signification pour tes
objets ?
Je dirais que la clé, c'est prèsque l'inverse : si l'identité a
de l'importance pour l'objet, il faut lui donner une sémantique de
référence. Sinon, une sémantique de valeur (au moins qu'il y a
d'autres contraints, comme le polymorphisme).
En général, les objets avec une sémantique de valeur
offrent moins de contraintes et sont donc plus faciles à
utiliser.
Et c'est là où je me sépare de toi. Il n'y a pas un qui offre
moins de contraintes et qui est plus facile à utiliser.
...
Ce dont il faut bien se rendre compte, quand même, c'est que chaque
langage a ces propres idiomes, plus ou moins consacré, pour
implémenter ces deux sémantiques. Et que l'idiome de valeur en
C++, c'est bien la copie (profonde) de l'objet, et non le pointeur.
Typiquement, c'est même très rare qu'on soit amené à allouer
dynamiquement un objet à sémantique de valeur.
(L'implémentation des objets à sémantique de valeur peut
très bien utiliser la mémoire dynamique, quand par exemple la
taille ou la structure de l'objet peut varier dynamiquement. Mais à
ce moment-là, c'est un détail de l'implémentation de l'objet.)
"Christophe Lephay" writes:La notion de valeur a-t-elle une quelconque signification pour tes
objets ?
Je dirais que la clé, c'est prèsque l'inverse : si l'identité a
de l'importance pour l'objet, il faut lui donner une sémantique de
référence. Sinon, une sémantique de valeur (au moins qu'il y a
d'autres contraints, comme le polymorphisme).
En général, les objets avec une sémantique de valeur
offrent moins de contraintes et sont donc plus faciles à
utiliser.
Et c'est là où je me sépare de toi. Il n'y a pas un qui offre
moins de contraintes et qui est plus facile à utiliser.
...
Ce dont il faut bien se rendre compte, quand même, c'est que chaque
langage a ces propres idiomes, plus ou moins consacré, pour
implémenter ces deux sémantiques. Et que l'idiome de valeur en
C++, c'est bien la copie (profonde) de l'objet, et non le pointeur.
Typiquement, c'est même très rare qu'on soit amené à allouer
dynamiquement un objet à sémantique de valeur.
(L'implémentation des objets à sémantique de valeur peut
très bien utiliser la mémoire dynamique, quand par exemple la
taille ou la structure de l'objet peut varier dynamiquement. Mais à
ce moment-là, c'est un détail de l'implémentation de l'objet.)
Je dirais que la clé, c'est prèsque l'inverse : si l'identité a
de l'importance pour l'objet, il faut lui donner une sémantique de
référence. Sinon, une sémantique de valeur (au moins qu'il y a
d'autres contraints, comme le polymorphisme).
Néanmoins, je trouve que c'est la question inverse qui se pose dans son cas,
dans la mesure où il accède à ses objets via des pointeurs.
Je dirais que la clé, c'est prèsque l'inverse : si l'identité a
de l'importance pour l'objet, il faut lui donner une sémantique de
référence. Sinon, une sémantique de valeur (au moins qu'il y a
d'autres contraints, comme le polymorphisme).
Néanmoins, je trouve que c'est la question inverse qui se pose dans son cas,
dans la mesure où il accède à ses objets via des pointeurs.
Je dirais que la clé, c'est prèsque l'inverse : si l'identité a
de l'importance pour l'objet, il faut lui donner une sémantique de
référence. Sinon, une sémantique de valeur (au moins qu'il y a
d'autres contraints, comme le polymorphisme).
Néanmoins, je trouve que c'est la question inverse qui se pose dans son cas,
dans la mesure où il accède à ses objets via des pointeurs.
_Designing_ _Object_ _Oriented_ _C++_ _Applications_ _Using_ _the_
_Booch_ _Method_, de Robert Martin (ISBN 0-13-203837-4). Il est
malheureusement un peu périmé
_Designing_ _Object_ _Oriented_ _C++_ _Applications_ _Using_ _the_
_Booch_ _Method_, de Robert Martin (ISBN 0-13-203837-4). Il est
malheureusement un peu périmé
_Designing_ _Object_ _Oriented_ _C++_ _Applications_ _Using_ _the_
_Booch_ _Method_, de Robert Martin (ISBN 0-13-203837-4). Il est
malheureusement un peu périmé