Voila mon problème : j'ai un client qui souhaite que toutes les
classes définies dans le projet sur lequel je travaille soient sous
la forme canonique de Coplien (pour ceux qui ne connaissent pas :
constructeur par défaut, constructeur par copie, operateur
d'affectation et destructeur virtuel ou non).
Pour que ce soit plus clean (selon eux), le client demande que
toutes les classes dérivent d'une classe de base... Sauf que je ne
vois pas du tout l'intéret de faire ca car je ne vois pas en quoi ca
force à respecter la forme canonique de Coplien.
Concernant l'operateur d'affectation, si je le met virtuel (est ce quelque
chose de propre ?!)
comment puis je faire en sorte que les classes filles utilisent un
opérateur correct ? cast dynamique ?
Concernant l'operateur de recopie, là, je vois pas du tout du tout du tout
:)
Bref, je comprends pas du tout cette demande, si quelqu'un pense que c'est
raisonable ou explicable, je veux bien une précision sur l'utilité...
Pour terminer, il faut aussi déporter le code du constructeur et du
destructeur dans une fonction séparée, et là, je comprends plus du
tout... genre quelque chose comme ca :
Voila mon problème : j'ai un client qui souhaite que toutes les
classes définies dans le projet sur lequel je travaille soient sous
la forme canonique de Coplien (pour ceux qui ne connaissent pas :
constructeur par défaut, constructeur par copie, operateur
d'affectation et destructeur virtuel ou non).
Pour que ce soit plus clean (selon eux), le client demande que
toutes les classes dérivent d'une classe de base... Sauf que je ne
vois pas du tout l'intéret de faire ca car je ne vois pas en quoi ca
force à respecter la forme canonique de Coplien.
Concernant l'operateur d'affectation, si je le met virtuel (est ce quelque
chose de propre ?!)
comment puis je faire en sorte que les classes filles utilisent un
opérateur correct ? cast dynamique ?
Concernant l'operateur de recopie, là, je vois pas du tout du tout du tout
:)
Bref, je comprends pas du tout cette demande, si quelqu'un pense que c'est
raisonable ou explicable, je veux bien une précision sur l'utilité...
Pour terminer, il faut aussi déporter le code du constructeur et du
destructeur dans une fonction séparée, et là, je comprends plus du
tout... genre quelque chose comme ca :
Voila mon problème : j'ai un client qui souhaite que toutes les
classes définies dans le projet sur lequel je travaille soient sous
la forme canonique de Coplien (pour ceux qui ne connaissent pas :
constructeur par défaut, constructeur par copie, operateur
d'affectation et destructeur virtuel ou non).
Pour que ce soit plus clean (selon eux), le client demande que
toutes les classes dérivent d'une classe de base... Sauf que je ne
vois pas du tout l'intéret de faire ca car je ne vois pas en quoi ca
force à respecter la forme canonique de Coplien.
Concernant l'operateur d'affectation, si je le met virtuel (est ce quelque
chose de propre ?!)
comment puis je faire en sorte que les classes filles utilisent un
opérateur correct ? cast dynamique ?
Concernant l'operateur de recopie, là, je vois pas du tout du tout du tout
:)
Bref, je comprends pas du tout cette demande, si quelqu'un pense que c'est
raisonable ou explicable, je veux bien une précision sur l'utilité...
Pour terminer, il faut aussi déporter le code du constructeur et du
destructeur dans une fonction séparée, et là, je comprends plus du
tout... genre quelque chose comme ca :
Je ne comprends pas plus que toi. Faut demander au client.
Attention que pendant l'execution du constructeur et du destructeur,
le type dynamique n'est pas le plus derive. Autrement dit "les
virtuelles ne marchent pas".
Je ne comprends pas plus que toi. Faut demander au client.
Attention que pendant l'execution du constructeur et du destructeur,
le type dynamique n'est pas le plus derive. Autrement dit "les
virtuelles ne marchent pas".
Je ne comprends pas plus que toi. Faut demander au client.
Attention que pendant l'execution du constructeur et du destructeur,
le type dynamique n'est pas le plus derive. Autrement dit "les
virtuelles ne marchent pas".
Bonjour à tous,
Voila mon problème : j'ai un client qui souhaite que toutes les classes
définies dans le projet sur lequel je travaille soient sous la forme
canonique de Coplien (pour ceux qui ne connaissent pas : constructeur
par défaut, constructeur par copie, operateur d'affectation et
destructeur virtuel ou non). Pour que ce soit plus clean (selon eux), le
client demande que toutes les classes dérivent d'une classe de base...
Sauf que je ne vois pas du tout l'intéret de faire ca car je ne vois pas
en quoi ca force à respecter la forme canonique de Coplien.
Concernant l'operateur d'affectation, si je le met virtuel (est ce
quelque chose de propre ?!) comment puis je faire en sorte que les
classes filles utilisent un opérateur correct ? cast dynamique ?
Concernant l'operateur de recopie, là, je vois pas du tout du tout du
tout :)
Bref, je comprends pas du tout cette demande, si quelqu'un pense que
c'est raisonable ou explicable, je veux bien une précision sur l'utilité...
Pour terminer, il faut aussi déporter le code du constructeur et du
destructeur dans une fonction séparée, et là, je comprends plus du
tout... genre quelque chose comme ca :
T::T(void)
{
construct();
}
T::~T(void)
{
destruct();
}
void T::construct(void)
{
// ...
}
void T::destruct(void)
{
// ...
}
Voila voila, votre avis est le bienvenu :)
Merci d'avance,
Bonjour à tous,
Voila mon problème : j'ai un client qui souhaite que toutes les classes
définies dans le projet sur lequel je travaille soient sous la forme
canonique de Coplien (pour ceux qui ne connaissent pas : constructeur
par défaut, constructeur par copie, operateur d'affectation et
destructeur virtuel ou non). Pour que ce soit plus clean (selon eux), le
client demande que toutes les classes dérivent d'une classe de base...
Sauf que je ne vois pas du tout l'intéret de faire ca car je ne vois pas
en quoi ca force à respecter la forme canonique de Coplien.
Concernant l'operateur d'affectation, si je le met virtuel (est ce
quelque chose de propre ?!) comment puis je faire en sorte que les
classes filles utilisent un opérateur correct ? cast dynamique ?
Concernant l'operateur de recopie, là, je vois pas du tout du tout du
tout :)
Bref, je comprends pas du tout cette demande, si quelqu'un pense que
c'est raisonable ou explicable, je veux bien une précision sur l'utilité...
Pour terminer, il faut aussi déporter le code du constructeur et du
destructeur dans une fonction séparée, et là, je comprends plus du
tout... genre quelque chose comme ca :
T::T(void)
{
construct();
}
T::~T(void)
{
destruct();
}
void T::construct(void)
{
// ...
}
void T::destruct(void)
{
// ...
}
Voila voila, votre avis est le bienvenu :)
Merci d'avance,
Bonjour à tous,
Voila mon problème : j'ai un client qui souhaite que toutes les classes
définies dans le projet sur lequel je travaille soient sous la forme
canonique de Coplien (pour ceux qui ne connaissent pas : constructeur
par défaut, constructeur par copie, operateur d'affectation et
destructeur virtuel ou non). Pour que ce soit plus clean (selon eux), le
client demande que toutes les classes dérivent d'une classe de base...
Sauf que je ne vois pas du tout l'intéret de faire ca car je ne vois pas
en quoi ca force à respecter la forme canonique de Coplien.
Concernant l'operateur d'affectation, si je le met virtuel (est ce
quelque chose de propre ?!) comment puis je faire en sorte que les
classes filles utilisent un opérateur correct ? cast dynamique ?
Concernant l'operateur de recopie, là, je vois pas du tout du tout du
tout :)
Bref, je comprends pas du tout cette demande, si quelqu'un pense que
c'est raisonable ou explicable, je veux bien une précision sur l'utilité...
Pour terminer, il faut aussi déporter le code du constructeur et du
destructeur dans une fonction séparée, et là, je comprends plus du
tout... genre quelque chose comme ca :
T::T(void)
{
construct();
}
T::~T(void)
{
destruct();
}
void T::construct(void)
{
// ...
}
void T::destruct(void)
{
// ...
}
Voila voila, votre avis est le bienvenu :)
Merci d'avance,
Voila mon problème : j'ai un client qui souhaite que toutes les classes
définies dans le projet sur lequel je travaille soient sous la forme
canonique de Coplien (pour ceux qui ne connaissent pas : constructeur
par défaut, constructeur par copie, operateur d'affectation et
destructeur virtuel ou non).
Pour que ce soit plus clean (selon eux), le
client demande que toutes les classes dérivent d'une classe de base...
Sauf que je ne vois pas du tout l'intéret de faire ca car je ne vois pas
en quoi ca force à respecter la forme canonique de Coplien.
Bref, je comprends pas du tout cette demande, si quelqu'un pense que
c'est raisonable ou explicable, je veux bien une précision sur l'utilité...
Pour terminer, il faut aussi déporter le code du constructeur et du
destructeur dans une fonction séparée, et là, je comprends plus du
tout... genre quelque chose comme ca :
T::T(void)
{
construct();
}
T::~T(void)
{
destruct();
}
Voila voila, votre avis est le bienvenu :)
Voila mon problème : j'ai un client qui souhaite que toutes les classes
définies dans le projet sur lequel je travaille soient sous la forme
canonique de Coplien (pour ceux qui ne connaissent pas : constructeur
par défaut, constructeur par copie, operateur d'affectation et
destructeur virtuel ou non).
Pour que ce soit plus clean (selon eux), le
client demande que toutes les classes dérivent d'une classe de base...
Sauf que je ne vois pas du tout l'intéret de faire ca car je ne vois pas
en quoi ca force à respecter la forme canonique de Coplien.
Bref, je comprends pas du tout cette demande, si quelqu'un pense que
c'est raisonable ou explicable, je veux bien une précision sur l'utilité...
Pour terminer, il faut aussi déporter le code du constructeur et du
destructeur dans une fonction séparée, et là, je comprends plus du
tout... genre quelque chose comme ca :
T::T(void)
{
construct();
}
T::~T(void)
{
destruct();
}
Voila voila, votre avis est le bienvenu :)
Voila mon problème : j'ai un client qui souhaite que toutes les classes
définies dans le projet sur lequel je travaille soient sous la forme
canonique de Coplien (pour ceux qui ne connaissent pas : constructeur
par défaut, constructeur par copie, operateur d'affectation et
destructeur virtuel ou non).
Pour que ce soit plus clean (selon eux), le
client demande que toutes les classes dérivent d'une classe de base...
Sauf que je ne vois pas du tout l'intéret de faire ca car je ne vois pas
en quoi ca force à respecter la forme canonique de Coplien.
Bref, je comprends pas du tout cette demande, si quelqu'un pense que
c'est raisonable ou explicable, je veux bien une précision sur l'utilité...
Pour terminer, il faut aussi déporter le code du constructeur et du
destructeur dans une fonction séparée, et là, je comprends plus du
tout... genre quelque chose comme ca :
T::T(void)
{
construct();
}
T::~T(void)
{
destruct();
}
Voila voila, votre avis est le bienvenu :)
Jean-Marc Bourguet wrote:Je ne comprends pas plus que toi. Faut demander au client.
Attention que pendant l'execution du constructeur et du destructeur,
le type dynamique n'est pas le plus derive. Autrement dit "les
virtuelles ne marchent pas".
Je ne comprends pas ce que tu veux dire. D'apres ce que je sais (C++98)
- Les constructeurs ne peuvent pas etre virtuels, donc forcement
dans B::B(), this est de type B*. Et on ne peut pas appeler de
methode virtuelle dans le constructeur.
Pour faire des "factory" on fait l'inverse, une methode virtuelle
appelle le constructeur.
- un destructeur virtuel n'est pas different d'une autre methode
virtuelle sur ce point. Dans virtual B::~B(), this peut etre de type
D* ou D derive de B et on peut le retrouver avec un
dynamic_cast<>().
Peux-tu m'eclairer sur tes propos?
Jean-Marc Bourguet wrote:
Je ne comprends pas plus que toi. Faut demander au client.
Attention que pendant l'execution du constructeur et du destructeur,
le type dynamique n'est pas le plus derive. Autrement dit "les
virtuelles ne marchent pas".
Je ne comprends pas ce que tu veux dire. D'apres ce que je sais (C++98)
- Les constructeurs ne peuvent pas etre virtuels, donc forcement
dans B::B(), this est de type B*. Et on ne peut pas appeler de
methode virtuelle dans le constructeur.
Pour faire des "factory" on fait l'inverse, une methode virtuelle
appelle le constructeur.
- un destructeur virtuel n'est pas different d'une autre methode
virtuelle sur ce point. Dans virtual B::~B(), this peut etre de type
D* ou D derive de B et on peut le retrouver avec un
dynamic_cast<>().
Peux-tu m'eclairer sur tes propos?
Jean-Marc Bourguet wrote:Je ne comprends pas plus que toi. Faut demander au client.
Attention que pendant l'execution du constructeur et du destructeur,
le type dynamique n'est pas le plus derive. Autrement dit "les
virtuelles ne marchent pas".
Je ne comprends pas ce que tu veux dire. D'apres ce que je sais (C++98)
- Les constructeurs ne peuvent pas etre virtuels, donc forcement
dans B::B(), this est de type B*. Et on ne peut pas appeler de
methode virtuelle dans le constructeur.
Pour faire des "factory" on fait l'inverse, une methode virtuelle
appelle le constructeur.
- un destructeur virtuel n'est pas different d'une autre methode
virtuelle sur ce point. Dans virtual B::~B(), this peut etre de type
D* ou D derive de B et on peut le retrouver avec un
dynamic_cast<>().
Peux-tu m'eclairer sur tes propos?
Y a n n R e n a r d wrote:Bonjour à tous,
Voila mon problème : j'ai un client qui souhaite que toutes les classes
définies dans le projet sur lequel je travaille soient sous la forme
canonique de Coplien (pour ceux qui ne connaissent pas : constructeur par
défaut, constructeur par copie, operateur d'affectation et destructeur
virtuel ou non). Pour que ce soit plus clean (selon eux), le client
demande que toutes les classes dérivent d'une classe de base... Sauf que
je ne vois pas du tout l'intéret de faire ca car je ne vois pas en quoi
ca force à respecter la forme canonique de Coplien.
Concernant l'operateur d'affectation, si je le met virtuel (est ce
quelque chose de propre ?!) comment puis je faire en sorte que les
classes filles utilisent un opérateur correct ? cast dynamique ?
Concernant l'operateur de recopie, là, je vois pas du tout du tout du
tout :)
Bref, je comprends pas du tout cette demande, si quelqu'un pense que
c'est raisonable ou explicable, je veux bien une précision sur
l'utilité...
Je trouve ca effectivement tres interessant et rare de la part d'un
client qui doit deja etre experimente dans la gestion de gros
*projet C++* (d'autre langage OO n'ont pas ces problemes).
Ton client a probalement une vision long terme du projet avec un
soucis de qualite dans l'evolutivite. L'ultra-performance n'est pas
sa priorite. Il vise probablement une progammation differentielle
par contrat, c'est-a-dire que chaque classe de la hierachie fait un
peu du travail puis delegue le reste a sa classe de base. Le virtual
permet de sauter des etapes dans la hierarchie (par ex si un niveau
de classe n'a rien a ajouter ca passe directement a sa classe de
base). Les contrats permettent de verifier qu'a chaque niveau on est
bien de le domaine attendu en entree et en sortie.
Je dirais que c'est tres contraignant sur des petits programmes ou
on a une vue d'ensemble des le depart et que l'evolutivite n'est pas
la priorite. Sur un grand projet, les demandes de ton client sont
tres sensees.
Pour terminer, il faut aussi déporter le code du constructeur et du
destructeur dans une fonction séparée, et là, je comprends plus du
tout... genre quelque chose comme ca :
T::T(void)
{
construct();
}
Ca c'est l'inverse des factory.
Je pense que c'est pour du debug (trace, check, message de log) si
construct est virtuelle.
T::~T(void)
{
destruct();
}
idem si destruct est virtuelle.
void T::construct(void)
{
// ...
}
void T::destruct(void)
{
// ...
}
est-ce que dans la classe de base elle ne sont pas declaree virtuelles?
Y a n n R e n a r d wrote:
Bonjour à tous,
Voila mon problème : j'ai un client qui souhaite que toutes les classes
définies dans le projet sur lequel je travaille soient sous la forme
canonique de Coplien (pour ceux qui ne connaissent pas : constructeur par
défaut, constructeur par copie, operateur d'affectation et destructeur
virtuel ou non). Pour que ce soit plus clean (selon eux), le client
demande que toutes les classes dérivent d'une classe de base... Sauf que
je ne vois pas du tout l'intéret de faire ca car je ne vois pas en quoi
ca force à respecter la forme canonique de Coplien.
Concernant l'operateur d'affectation, si je le met virtuel (est ce
quelque chose de propre ?!) comment puis je faire en sorte que les
classes filles utilisent un opérateur correct ? cast dynamique ?
Concernant l'operateur de recopie, là, je vois pas du tout du tout du
tout :)
Bref, je comprends pas du tout cette demande, si quelqu'un pense que
c'est raisonable ou explicable, je veux bien une précision sur
l'utilité...
Je trouve ca effectivement tres interessant et rare de la part d'un
client qui doit deja etre experimente dans la gestion de gros
*projet C++* (d'autre langage OO n'ont pas ces problemes).
Ton client a probalement une vision long terme du projet avec un
soucis de qualite dans l'evolutivite. L'ultra-performance n'est pas
sa priorite. Il vise probablement une progammation differentielle
par contrat, c'est-a-dire que chaque classe de la hierachie fait un
peu du travail puis delegue le reste a sa classe de base. Le virtual
permet de sauter des etapes dans la hierarchie (par ex si un niveau
de classe n'a rien a ajouter ca passe directement a sa classe de
base). Les contrats permettent de verifier qu'a chaque niveau on est
bien de le domaine attendu en entree et en sortie.
Je dirais que c'est tres contraignant sur des petits programmes ou
on a une vue d'ensemble des le depart et que l'evolutivite n'est pas
la priorite. Sur un grand projet, les demandes de ton client sont
tres sensees.
Pour terminer, il faut aussi déporter le code du constructeur et du
destructeur dans une fonction séparée, et là, je comprends plus du
tout... genre quelque chose comme ca :
T::T(void)
{
construct();
}
Ca c'est l'inverse des factory.
Je pense que c'est pour du debug (trace, check, message de log) si
construct est virtuelle.
T::~T(void)
{
destruct();
}
idem si destruct est virtuelle.
void T::construct(void)
{
// ...
}
void T::destruct(void)
{
// ...
}
est-ce que dans la classe de base elle ne sont pas declaree virtuelles?
Y a n n R e n a r d wrote:Bonjour à tous,
Voila mon problème : j'ai un client qui souhaite que toutes les classes
définies dans le projet sur lequel je travaille soient sous la forme
canonique de Coplien (pour ceux qui ne connaissent pas : constructeur par
défaut, constructeur par copie, operateur d'affectation et destructeur
virtuel ou non). Pour que ce soit plus clean (selon eux), le client
demande que toutes les classes dérivent d'une classe de base... Sauf que
je ne vois pas du tout l'intéret de faire ca car je ne vois pas en quoi
ca force à respecter la forme canonique de Coplien.
Concernant l'operateur d'affectation, si je le met virtuel (est ce
quelque chose de propre ?!) comment puis je faire en sorte que les
classes filles utilisent un opérateur correct ? cast dynamique ?
Concernant l'operateur de recopie, là, je vois pas du tout du tout du
tout :)
Bref, je comprends pas du tout cette demande, si quelqu'un pense que
c'est raisonable ou explicable, je veux bien une précision sur
l'utilité...
Je trouve ca effectivement tres interessant et rare de la part d'un
client qui doit deja etre experimente dans la gestion de gros
*projet C++* (d'autre langage OO n'ont pas ces problemes).
Ton client a probalement une vision long terme du projet avec un
soucis de qualite dans l'evolutivite. L'ultra-performance n'est pas
sa priorite. Il vise probablement une progammation differentielle
par contrat, c'est-a-dire que chaque classe de la hierachie fait un
peu du travail puis delegue le reste a sa classe de base. Le virtual
permet de sauter des etapes dans la hierarchie (par ex si un niveau
de classe n'a rien a ajouter ca passe directement a sa classe de
base). Les contrats permettent de verifier qu'a chaque niveau on est
bien de le domaine attendu en entree et en sortie.
Je dirais que c'est tres contraignant sur des petits programmes ou
on a une vue d'ensemble des le depart et que l'evolutivite n'est pas
la priorite. Sur un grand projet, les demandes de ton client sont
tres sensees.
Pour terminer, il faut aussi déporter le code du constructeur et du
destructeur dans une fonction séparée, et là, je comprends plus du
tout... genre quelque chose comme ca :
T::T(void)
{
construct();
}
Ca c'est l'inverse des factory.
Je pense que c'est pour du debug (trace, check, message de log) si
construct est virtuelle.
T::~T(void)
{
destruct();
}
idem si destruct est virtuelle.
void T::construct(void)
{
// ...
}
void T::destruct(void)
{
// ...
}
est-ce que dans la classe de base elle ne sont pas declaree virtuelles?
Laurent Deniau writes:Jean-Marc Bourguet wrote:Je ne comprends pas plus que toi. Faut demander au client.
Attention que pendant l'execution du constructeur et du destructeur,
le type dynamique n'est pas le plus derive. Autrement dit "les
virtuelles ne marchent pas".
Je ne comprends pas ce que tu veux dire. D'apres ce que je sais (C++98)
- Les constructeurs ne peuvent pas etre virtuels, donc forcement
dans B::B(), this est de type B*. Et on ne peut pas appeler de
methode virtuelle dans le constructeur.
Si on peut appeler des membres virtuels. Mais leur resolution n'est
pas celle a laquelle certains (en particulier ceux qui ont fait du
Java) s'attende.Pour faire des "factory" on fait l'inverse, une methode virtuelle
appelle le constructeur.
- un destructeur virtuel n'est pas different d'une autre methode
virtuelle sur ce point. Dans virtual B::~B(), this peut etre de type
D* ou D derive de B et on peut le retrouver avec un
dynamic_cast<>().
Non.Peux-tu m'eclairer sur tes propos?
Pendant l'execution du constructeur et du destructeur, l'objet est du
type de la classe construite (et non de la classe la plus derivee).
Appeler un membre virtuel sur this a un comportement defini: la
fonction sera celle de la classe construite ou de l'ancetre la
fournissant (donc c'est un probleme si elle est pure).
Appeler un membre virtuel a travers d'un alias de this qui n'est pas
du type construit ou d'un de ses descendants est indefini.
Les references:
Laurent Deniau <Laurent.Deniau@cern.ch> writes:
Jean-Marc Bourguet wrote:
Je ne comprends pas plus que toi. Faut demander au client.
Attention que pendant l'execution du constructeur et du destructeur,
le type dynamique n'est pas le plus derive. Autrement dit "les
virtuelles ne marchent pas".
Je ne comprends pas ce que tu veux dire. D'apres ce que je sais (C++98)
- Les constructeurs ne peuvent pas etre virtuels, donc forcement
dans B::B(), this est de type B*. Et on ne peut pas appeler de
methode virtuelle dans le constructeur.
Si on peut appeler des membres virtuels. Mais leur resolution n'est
pas celle a laquelle certains (en particulier ceux qui ont fait du
Java) s'attende.
Pour faire des "factory" on fait l'inverse, une methode virtuelle
appelle le constructeur.
- un destructeur virtuel n'est pas different d'une autre methode
virtuelle sur ce point. Dans virtual B::~B(), this peut etre de type
D* ou D derive de B et on peut le retrouver avec un
dynamic_cast<>().
Non.
Peux-tu m'eclairer sur tes propos?
Pendant l'execution du constructeur et du destructeur, l'objet est du
type de la classe construite (et non de la classe la plus derivee).
Appeler un membre virtuel sur this a un comportement defini: la
fonction sera celle de la classe construite ou de l'ancetre la
fournissant (donc c'est un probleme si elle est pure).
Appeler un membre virtuel a travers d'un alias de this qui n'est pas
du type construit ou d'un de ses descendants est indefini.
Les references:
Laurent Deniau writes:Jean-Marc Bourguet wrote:Je ne comprends pas plus que toi. Faut demander au client.
Attention que pendant l'execution du constructeur et du destructeur,
le type dynamique n'est pas le plus derive. Autrement dit "les
virtuelles ne marchent pas".
Je ne comprends pas ce que tu veux dire. D'apres ce que je sais (C++98)
- Les constructeurs ne peuvent pas etre virtuels, donc forcement
dans B::B(), this est de type B*. Et on ne peut pas appeler de
methode virtuelle dans le constructeur.
Si on peut appeler des membres virtuels. Mais leur resolution n'est
pas celle a laquelle certains (en particulier ceux qui ont fait du
Java) s'attende.Pour faire des "factory" on fait l'inverse, une methode virtuelle
appelle le constructeur.
- un destructeur virtuel n'est pas different d'une autre methode
virtuelle sur ce point. Dans virtual B::~B(), this peut etre de type
D* ou D derive de B et on peut le retrouver avec un
dynamic_cast<>().
Non.Peux-tu m'eclairer sur tes propos?
Pendant l'execution du constructeur et du destructeur, l'objet est du
type de la classe construite (et non de la classe la plus derivee).
Appeler un membre virtuel sur this a un comportement defini: la
fonction sera celle de la classe construite ou de l'ancetre la
fournissant (donc c'est un probleme si elle est pure).
Appeler un membre virtuel a travers d'un alias de this qui n'est pas
du type construit ou d'un de ses descendants est indefini.
Les references:
Pendant l'execution du constructeur et du destructeur, l'objet est
du type de la classe construite (et non de la classe la plus
derivee).
Je savais pour les constructeurs (ce qui me fait penser que j'ai dit
une betise dans l'autre post, le virtual de construct et destruct
est inutile), mais je ne savais pas pour les destructeurs... Autant
le premier me parait logique autant j'ai du mal a comprendre la
raison du second.
Un probleme de ressources associees a la vtbl (la vtbl elle-meme?)?Appeler un membre virtuel sur this a un comportement defini: la
fonction sera celle de la classe construite ou de l'ancetre la
fournissant (donc c'est un probleme si elle est pure).
Juste. Sauf si la methode virtual appellee n'utilise pas this (12.7/3),
mais je ne vois pas a quoi elle servirait (du debug?).
Pendant l'execution du constructeur et du destructeur, l'objet est
du type de la classe construite (et non de la classe la plus
derivee).
Je savais pour les constructeurs (ce qui me fait penser que j'ai dit
une betise dans l'autre post, le virtual de construct et destruct
est inutile), mais je ne savais pas pour les destructeurs... Autant
le premier me parait logique autant j'ai du mal a comprendre la
raison du second.
Un probleme de ressources associees a la vtbl (la vtbl elle-meme?)?
Appeler un membre virtuel sur this a un comportement defini: la
fonction sera celle de la classe construite ou de l'ancetre la
fournissant (donc c'est un probleme si elle est pure).
Juste. Sauf si la methode virtual appellee n'utilise pas this (12.7/3),
mais je ne vois pas a quoi elle servirait (du debug?).
Pendant l'execution du constructeur et du destructeur, l'objet est
du type de la classe construite (et non de la classe la plus
derivee).
Je savais pour les constructeurs (ce qui me fait penser que j'ai dit
une betise dans l'autre post, le virtual de construct et destruct
est inutile), mais je ne savais pas pour les destructeurs... Autant
le premier me parait logique autant j'ai du mal a comprendre la
raison du second.
Un probleme de ressources associees a la vtbl (la vtbl elle-meme?)?Appeler un membre virtuel sur this a un comportement defini: la
fonction sera celle de la classe construite ou de l'ancetre la
fournissant (donc c'est un probleme si elle est pure).
Juste. Sauf si la methode virtual appellee n'utilise pas this (12.7/3),
mais je ne vois pas a quoi elle servirait (du debug?).
Laurent Deniau writes:Y a n n R e n a r d wrote:Bonjour à tous,
Voila mon problème : j'ai un client qui souhaite que toutes les classes
définies dans le projet sur lequel je travaille soient sous la forme
canonique de Coplien (pour ceux qui ne connaissent pas : constructeur par
défaut, constructeur par copie, operateur d'affectation et destructeur
virtuel ou non). Pour que ce soit plus clean (selon eux), le client
demande que toutes les classes dérivent d'une classe de base... Sauf que
je ne vois pas du tout l'intéret de faire ca car je ne vois pas en quoi
ca force à respecter la forme canonique de Coplien.
Concernant l'operateur d'affectation, si je le met virtuel (est ce
quelque chose de propre ?!) comment puis je faire en sorte que les
classes filles utilisent un opérateur correct ? cast dynamique ?
Concernant l'operateur de recopie, là, je vois pas du tout du tout du
tout :)
Bref, je comprends pas du tout cette demande, si quelqu'un pense que
c'est raisonable ou explicable, je veux bien une précision sur
l'utilité...
Je trouve ca effectivement tres interessant et rare de la part d'un
client qui doit deja etre experimente dans la gestion de gros
*projet C++* (d'autre langage OO n'ont pas ces problemes).
Que demande t'il?
- que toutes les classes soient avec
* constructeur par defaut, desole j'ai des classes qui n'en
ont pas et je ne vois aucune raison d'en imposer un
artificiel
* destructeur: ce n'est pas possible de faire autrement
* assignement et constructeur de copie: je perds mon temps
a les desactiver dans au moins la moitie de mes classes
- que toutes les classes derivent d'une classe de base
* c'est impraticable (comment on fait pour imposer la classe
de base de std::vector, de classes derivees a partir
d'elements d'une bibliotheque tierce ?)
* si c'est pour imposer la forme canonique je ne vois pas
comment faire (tiens sauf pour qqch du genre NotCopiable...
mais avec une telle classe de base, definir l'assignement
et le constructeur de copie, c'est de la perversite)
* ca me fait plutot penser a quelqu'un qui a de l'experience
d'un autre langage ou cette classe de base est presente
d'office que du C++ (tiens bizarrement c'etait la mode au
debut du C++ quand pour une partie des gens OO signifiait
SmallTalk)
- de faire faire le travail des constructeurs et destructeurs par
une autre fonction, pourquoi?Ton client a probalement une vision long terme du projet avec un
soucis de qualite dans l'evolutivite. L'ultra-performance n'est pas
sa priorite. Il vise probablement une progammation differentielle
par contrat, c'est-a-dire que chaque classe de la hierachie fait un
peu du travail puis delegue le reste a sa classe de base. Le virtual
permet de sauter des etapes dans la hierarchie (par ex si un niveau
de classe n'a rien a ajouter ca passe directement a sa classe de
base). Les contrats permettent de verifier qu'a chaque niveau on est
bien de le domaine attendu en entree et en sortie.
Je dirais que c'est tres contraignant sur des petits programmes ou
on a une vue d'ensemble des le depart et que l'evolutivite n'est pas
la priorite. Sur un grand projet, les demandes de ton client sont
tres sensees.
Je ne vois guere de sens. Il me semble pourtant que j'ai l'experience
de gros projets.Pour terminer, il faut aussi déporter le code du constructeur et du
destructeur dans une fonction séparée, et là, je comprends plus du
tout... genre quelque chose comme ca :
T::T(void)
{
construct();
}
Ca c'est l'inverse des factory.
Je pense que c'est pour du debug (trace, check, message de log) si
construct est virtuelle.
Expliques-toi, je ne vois pas l'utilite de faire ca systematiquement,
meme avec un objectif d'instrumentation.T::~T(void)
{
destruct();
}
idem si destruct est virtuelle.
A nouveau je ne vois pas l'utilite.void T::construct(void)
{
// ...
}
void T::destruct(void)
{
// ...
}
est-ce que dans la classe de base elle ne sont pas declaree virtuelles?
Qu'est-ce que ca change?
Laurent Deniau <Laurent.Deniau@cern.ch> writes:
Y a n n R e n a r d wrote:
Bonjour à tous,
Voila mon problème : j'ai un client qui souhaite que toutes les classes
définies dans le projet sur lequel je travaille soient sous la forme
canonique de Coplien (pour ceux qui ne connaissent pas : constructeur par
défaut, constructeur par copie, operateur d'affectation et destructeur
virtuel ou non). Pour que ce soit plus clean (selon eux), le client
demande que toutes les classes dérivent d'une classe de base... Sauf que
je ne vois pas du tout l'intéret de faire ca car je ne vois pas en quoi
ca force à respecter la forme canonique de Coplien.
Concernant l'operateur d'affectation, si je le met virtuel (est ce
quelque chose de propre ?!) comment puis je faire en sorte que les
classes filles utilisent un opérateur correct ? cast dynamique ?
Concernant l'operateur de recopie, là, je vois pas du tout du tout du
tout :)
Bref, je comprends pas du tout cette demande, si quelqu'un pense que
c'est raisonable ou explicable, je veux bien une précision sur
l'utilité...
Je trouve ca effectivement tres interessant et rare de la part d'un
client qui doit deja etre experimente dans la gestion de gros
*projet C++* (d'autre langage OO n'ont pas ces problemes).
Que demande t'il?
- que toutes les classes soient avec
* constructeur par defaut, desole j'ai des classes qui n'en
ont pas et je ne vois aucune raison d'en imposer un
artificiel
* destructeur: ce n'est pas possible de faire autrement
* assignement et constructeur de copie: je perds mon temps
a les desactiver dans au moins la moitie de mes classes
- que toutes les classes derivent d'une classe de base
* c'est impraticable (comment on fait pour imposer la classe
de base de std::vector, de classes derivees a partir
d'elements d'une bibliotheque tierce ?)
* si c'est pour imposer la forme canonique je ne vois pas
comment faire (tiens sauf pour qqch du genre NotCopiable...
mais avec une telle classe de base, definir l'assignement
et le constructeur de copie, c'est de la perversite)
* ca me fait plutot penser a quelqu'un qui a de l'experience
d'un autre langage ou cette classe de base est presente
d'office que du C++ (tiens bizarrement c'etait la mode au
debut du C++ quand pour une partie des gens OO signifiait
SmallTalk)
- de faire faire le travail des constructeurs et destructeurs par
une autre fonction, pourquoi?
Ton client a probalement une vision long terme du projet avec un
soucis de qualite dans l'evolutivite. L'ultra-performance n'est pas
sa priorite. Il vise probablement une progammation differentielle
par contrat, c'est-a-dire que chaque classe de la hierachie fait un
peu du travail puis delegue le reste a sa classe de base. Le virtual
permet de sauter des etapes dans la hierarchie (par ex si un niveau
de classe n'a rien a ajouter ca passe directement a sa classe de
base). Les contrats permettent de verifier qu'a chaque niveau on est
bien de le domaine attendu en entree et en sortie.
Je dirais que c'est tres contraignant sur des petits programmes ou
on a une vue d'ensemble des le depart et que l'evolutivite n'est pas
la priorite. Sur un grand projet, les demandes de ton client sont
tres sensees.
Je ne vois guere de sens. Il me semble pourtant que j'ai l'experience
de gros projets.
Pour terminer, il faut aussi déporter le code du constructeur et du
destructeur dans une fonction séparée, et là, je comprends plus du
tout... genre quelque chose comme ca :
T::T(void)
{
construct();
}
Ca c'est l'inverse des factory.
Je pense que c'est pour du debug (trace, check, message de log) si
construct est virtuelle.
Expliques-toi, je ne vois pas l'utilite de faire ca systematiquement,
meme avec un objectif d'instrumentation.
T::~T(void)
{
destruct();
}
idem si destruct est virtuelle.
A nouveau je ne vois pas l'utilite.
void T::construct(void)
{
// ...
}
void T::destruct(void)
{
// ...
}
est-ce que dans la classe de base elle ne sont pas declaree virtuelles?
Qu'est-ce que ca change?
Laurent Deniau writes:Y a n n R e n a r d wrote:Bonjour à tous,
Voila mon problème : j'ai un client qui souhaite que toutes les classes
définies dans le projet sur lequel je travaille soient sous la forme
canonique de Coplien (pour ceux qui ne connaissent pas : constructeur par
défaut, constructeur par copie, operateur d'affectation et destructeur
virtuel ou non). Pour que ce soit plus clean (selon eux), le client
demande que toutes les classes dérivent d'une classe de base... Sauf que
je ne vois pas du tout l'intéret de faire ca car je ne vois pas en quoi
ca force à respecter la forme canonique de Coplien.
Concernant l'operateur d'affectation, si je le met virtuel (est ce
quelque chose de propre ?!) comment puis je faire en sorte que les
classes filles utilisent un opérateur correct ? cast dynamique ?
Concernant l'operateur de recopie, là, je vois pas du tout du tout du
tout :)
Bref, je comprends pas du tout cette demande, si quelqu'un pense que
c'est raisonable ou explicable, je veux bien une précision sur
l'utilité...
Je trouve ca effectivement tres interessant et rare de la part d'un
client qui doit deja etre experimente dans la gestion de gros
*projet C++* (d'autre langage OO n'ont pas ces problemes).
Que demande t'il?
- que toutes les classes soient avec
* constructeur par defaut, desole j'ai des classes qui n'en
ont pas et je ne vois aucune raison d'en imposer un
artificiel
* destructeur: ce n'est pas possible de faire autrement
* assignement et constructeur de copie: je perds mon temps
a les desactiver dans au moins la moitie de mes classes
- que toutes les classes derivent d'une classe de base
* c'est impraticable (comment on fait pour imposer la classe
de base de std::vector, de classes derivees a partir
d'elements d'une bibliotheque tierce ?)
* si c'est pour imposer la forme canonique je ne vois pas
comment faire (tiens sauf pour qqch du genre NotCopiable...
mais avec une telle classe de base, definir l'assignement
et le constructeur de copie, c'est de la perversite)
* ca me fait plutot penser a quelqu'un qui a de l'experience
d'un autre langage ou cette classe de base est presente
d'office que du C++ (tiens bizarrement c'etait la mode au
debut du C++ quand pour une partie des gens OO signifiait
SmallTalk)
- de faire faire le travail des constructeurs et destructeurs par
une autre fonction, pourquoi?Ton client a probalement une vision long terme du projet avec un
soucis de qualite dans l'evolutivite. L'ultra-performance n'est pas
sa priorite. Il vise probablement une progammation differentielle
par contrat, c'est-a-dire que chaque classe de la hierachie fait un
peu du travail puis delegue le reste a sa classe de base. Le virtual
permet de sauter des etapes dans la hierarchie (par ex si un niveau
de classe n'a rien a ajouter ca passe directement a sa classe de
base). Les contrats permettent de verifier qu'a chaque niveau on est
bien de le domaine attendu en entree et en sortie.
Je dirais que c'est tres contraignant sur des petits programmes ou
on a une vue d'ensemble des le depart et que l'evolutivite n'est pas
la priorite. Sur un grand projet, les demandes de ton client sont
tres sensees.
Je ne vois guere de sens. Il me semble pourtant que j'ai l'experience
de gros projets.Pour terminer, il faut aussi déporter le code du constructeur et du
destructeur dans une fonction séparée, et là, je comprends plus du
tout... genre quelque chose comme ca :
T::T(void)
{
construct();
}
Ca c'est l'inverse des factory.
Je pense que c'est pour du debug (trace, check, message de log) si
construct est virtuelle.
Expliques-toi, je ne vois pas l'utilite de faire ca systematiquement,
meme avec un objectif d'instrumentation.T::~T(void)
{
destruct();
}
idem si destruct est virtuelle.
A nouveau je ne vois pas l'utilite.void T::construct(void)
{
// ...
}
void T::destruct(void)
{
// ...
}
est-ce que dans la classe de base elle ne sont pas declaree virtuelles?
Qu'est-ce que ca change?
Laurent Deniau writes:Pendant l'execution du constructeur et du destructeur, l'objet est
du type de la classe construite (et non de la classe la plus
derivee).
Je savais pour les constructeurs (ce qui me fait penser que j'ai dit
une betise dans l'autre post, le virtual de construct et destruct
est inutile), mais je ne savais pas pour les destructeurs... Autant
le premier me parait logique autant j'ai du mal a comprendre la
raison du second.
Exactement les raisons symetriques. Par exemple lors de l'execution
du constructeur, les membres des classes descendantes n'ont pas encore
ete construit, pendant l'execution du destructeur ils ont deja ete
detruits.Un probleme de ressources associees a la vtbl (la vtbl elle-meme?)?
Appeler un membre virtuel sur this a un comportement defini: la
fonction sera celle de la classe construite ou de l'ancetre la
fournissant (donc c'est un probleme si elle est pure).
Juste. Sauf si la methode virtual appellee n'utilise pas this (12.7/3),
mais je ne vois pas a quoi elle servirait (du debug?).
Je ne vois pas ou tu lis ca dans 12.7/3.
Laurent Deniau <Laurent.Deniau@cern.ch> writes:
Pendant l'execution du constructeur et du destructeur, l'objet est
du type de la classe construite (et non de la classe la plus
derivee).
Je savais pour les constructeurs (ce qui me fait penser que j'ai dit
une betise dans l'autre post, le virtual de construct et destruct
est inutile), mais je ne savais pas pour les destructeurs... Autant
le premier me parait logique autant j'ai du mal a comprendre la
raison du second.
Exactement les raisons symetriques. Par exemple lors de l'execution
du constructeur, les membres des classes descendantes n'ont pas encore
ete construit, pendant l'execution du destructeur ils ont deja ete
detruits.
Un probleme de ressources associees a la vtbl (la vtbl elle-meme?)?
Appeler un membre virtuel sur this a un comportement defini: la
fonction sera celle de la classe construite ou de l'ancetre la
fournissant (donc c'est un probleme si elle est pure).
Juste. Sauf si la methode virtual appellee n'utilise pas this (12.7/3),
mais je ne vois pas a quoi elle servirait (du debug?).
Je ne vois pas ou tu lis ca dans 12.7/3.
Laurent Deniau writes:Pendant l'execution du constructeur et du destructeur, l'objet est
du type de la classe construite (et non de la classe la plus
derivee).
Je savais pour les constructeurs (ce qui me fait penser que j'ai dit
une betise dans l'autre post, le virtual de construct et destruct
est inutile), mais je ne savais pas pour les destructeurs... Autant
le premier me parait logique autant j'ai du mal a comprendre la
raison du second.
Exactement les raisons symetriques. Par exemple lors de l'execution
du constructeur, les membres des classes descendantes n'ont pas encore
ete construit, pendant l'execution du destructeur ils ont deja ete
detruits.Un probleme de ressources associees a la vtbl (la vtbl elle-meme?)?
Appeler un membre virtuel sur this a un comportement defini: la
fonction sera celle de la classe construite ou de l'ancetre la
fournissant (donc c'est un probleme si elle est pure).
Juste. Sauf si la methode virtual appellee n'utilise pas this (12.7/3),
mais je ne vois pas a quoi elle servirait (du debug?).
Je ne vois pas ou tu lis ca dans 12.7/3.