choix entre dynamic_cast et une fonction virtuelle d'identification
7 réponses
Marc G
Bonjour,
J'ai une hiérarchie de classes dérivées d'une même classe de base Base, pour
simplifier, quelque chose qui ressemble à ce qui suit :
class Base {
enum ID { ID1,ID2};
virtual ID id() { throw; }
};
class Derivee1 : public Base {
virtual ID id() { return ID1; }
};
class Derivee2 : public Base {
virtual ID id() { return ID2; }
};
Dans mon application, la performance est importante
=> je voudrais savoir quelle méthode est la + rapide pour "identifier" une
classe à partir d'un pointeur sur la classe de base
Base *ptr=new Derivee1 ;
choix 1 :
if (ptr->id()==ID1)
...
ou choix2
if (dynamic_cast<Derivee1*>(ptr))
...
A priori, les deux sont équivalentes (et la seconde présente l'avantage
d'éviter l'oubli de la redéfinition de méthode virtuelle...)
Est-ce bien le cas ?
Merci à vous.
Marc
Cette action est irreversible, confirmez la suppression du commentaire ?
Signaler le commentaire
Veuillez sélectionner un problème
Nudité
Violence
Harcèlement
Fraude
Vente illégale
Discours haineux
Terrorisme
Autre
Michael DOUBEZ
Marc G a écrit :
J'ai une hiérarchie de classes dérivées d'une même classe de base Base, pour simplifier, quelque chose qui ressemble à ce qui suit :
class Base { enum ID { ID1,ID2}; virtual ID id() { throw; } };
class Derivee1 : public Base { virtual ID id() { return ID1; } };
class Derivee2 : public Base { virtual ID id() { return ID2; } };
Dans mon application, la performance est importante => je voudrais savoir quelle méthode est la + rapide pour "identifier" une classe à partir d'un pointeur sur la classe de base
Base *ptr=new Derivee1 ;
choix 1 : if (ptr->id()==ID1) ... ou choix2 if (dynamic_cast<Derivee1*>(ptr)) ...
A priori, les deux sont équivalentes (et la seconde présente l'avantage d'éviter l'oubli de la redéfinition de méthode virtuelle...)
Pour ne pas oublier de redéfinir la méthode virtuelle tu peux aussi la rendre virtuelle pure.
Est-ce bien le cas ?
Je ne sais pas, AMA ça dépends de la qualité du compilateur.
-- Michael
Marc G a écrit :
J'ai une hiérarchie de classes dérivées d'une même classe de base Base,
pour simplifier, quelque chose qui ressemble à ce qui suit :
class Base {
enum ID { ID1,ID2};
virtual ID id() { throw; }
};
class Derivee1 : public Base {
virtual ID id() { return ID1; }
};
class Derivee2 : public Base {
virtual ID id() { return ID2; }
};
Dans mon application, la performance est importante
=> je voudrais savoir quelle méthode est la + rapide pour "identifier"
une classe à partir d'un pointeur sur la classe de base
Base *ptr=new Derivee1 ;
choix 1 :
if (ptr->id()==ID1)
...
ou choix2
if (dynamic_cast<Derivee1*>(ptr))
...
A priori, les deux sont équivalentes (et la seconde présente l'avantage
d'éviter l'oubli de la redéfinition de méthode virtuelle...)
Pour ne pas oublier de redéfinir la méthode virtuelle tu peux aussi la
rendre virtuelle pure.
Est-ce bien le cas ?
Je ne sais pas, AMA ça dépends de la qualité du compilateur.
J'ai une hiérarchie de classes dérivées d'une même classe de base Base, pour simplifier, quelque chose qui ressemble à ce qui suit :
class Base { enum ID { ID1,ID2}; virtual ID id() { throw; } };
class Derivee1 : public Base { virtual ID id() { return ID1; } };
class Derivee2 : public Base { virtual ID id() { return ID2; } };
Dans mon application, la performance est importante => je voudrais savoir quelle méthode est la + rapide pour "identifier" une classe à partir d'un pointeur sur la classe de base
Base *ptr=new Derivee1 ;
choix 1 : if (ptr->id()==ID1) ... ou choix2 if (dynamic_cast<Derivee1*>(ptr)) ...
A priori, les deux sont équivalentes (et la seconde présente l'avantage d'éviter l'oubli de la redéfinition de méthode virtuelle...)
Pour ne pas oublier de redéfinir la méthode virtuelle tu peux aussi la rendre virtuelle pure.
Est-ce bien le cas ?
Je ne sais pas, AMA ça dépends de la qualité du compilateur.
-- Michael
Marc G
> Pour ne pas oublier de redéfinir la méthode virtuelle tu peux aussi la rendre virtuelle pure.
oui, c'est certainement ce qu'il faut faire... Je viens d'essayer et l'appel de la méthode virtuelle semble nettement plus rapide (environ 7 fois + sur BCB). Je ne comprends pas trop pourquoi mais bon, puisque c'est comme ça... En fait je connais le mécanisme d'implémentation des tables virtuelles mais pas celui des dynamic_cast... (peut-être qu'il s'appuie sur une fonction virtuelle d'identification justement, d'où le temps + élevé ?) Si quelqu'un en sait plus... Marc
> Pour ne pas oublier de redéfinir la méthode virtuelle tu peux aussi la
rendre virtuelle pure.
oui, c'est certainement ce qu'il faut faire...
Je viens d'essayer et l'appel de la méthode virtuelle semble nettement plus
rapide (environ 7 fois + sur BCB).
Je ne comprends pas trop pourquoi mais bon, puisque c'est comme ça...
En fait je connais le mécanisme d'implémentation des tables virtuelles mais
pas celui des dynamic_cast...
(peut-être qu'il s'appuie sur une fonction virtuelle d'identification
justement, d'où le temps + élevé ?)
Si quelqu'un en sait plus...
Marc
> Pour ne pas oublier de redéfinir la méthode virtuelle tu peux aussi la rendre virtuelle pure.
oui, c'est certainement ce qu'il faut faire... Je viens d'essayer et l'appel de la méthode virtuelle semble nettement plus rapide (environ 7 fois + sur BCB). Je ne comprends pas trop pourquoi mais bon, puisque c'est comme ça... En fait je connais le mécanisme d'implémentation des tables virtuelles mais pas celui des dynamic_cast... (peut-être qu'il s'appuie sur une fonction virtuelle d'identification justement, d'où le temps + élevé ?) Si quelqu'un en sait plus... Marc
James Kanze
On Jul 29, 9:41 pm, "Marc G" wrote:
J'ai une hiérarchie de classes dérivées d'une même classe de base Base, pour simplifier, quelque chose qui ressemble à ce qui suit :
class Base { enum ID { ID1,ID2}; virtual ID id() { throw; } };
class Derivee1 : public Base { virtual ID id() { return ID1; } };
class Derivee2 : public Base { virtual ID id() { return ID2; } };
Dans mon application, la performance est importante => je voudrais savoir quelle méthode est la + rapide pour "identifier" une classe à partir d'un pointeur sur la classe de base
La meilleur façon, c'est de ne pas avoir besoin de les identifier. En général, s'il faut savoir la classe dérivée à partir d'un pointeur à la classe de base, il y a quelque chose qui ne colle pas. (Il y a des exceptions, évidemment.)
Base *ptr=new Derivee1 ;
choix 1 : if (ptr->id()==ID1) ... ou choix2 if (dynamic_cast<Derivee1*>(ptr)) ...
A priori, les deux sont équivalentes (et la seconde présente l'avantage d'éviter l'oubli de la redéfinition de méthode virtuelle...)
Tout dépend du compilateur, mais en général, le dynamic_cast est plus lourd et plus cher que l'appel d'une fonction viruelle.
-- James Kanze (GABI Software) email: Conseils en informatique orientée objet/ Beratung in objektorientierter Datenverarbeitung 9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
On Jul 29, 9:41 pm, "Marc G" <mgueg...@metrica.fr> wrote:
J'ai une hiérarchie de classes dérivées d'une même classe de
base Base, pour simplifier, quelque chose qui ressemble à ce
qui suit :
class Base {
enum ID { ID1,ID2};
virtual ID id() { throw; }
};
class Derivee1 : public Base {
virtual ID id() { return ID1; }
};
class Derivee2 : public Base {
virtual ID id() { return ID2; }
};
Dans mon application, la performance est importante => je
voudrais savoir quelle méthode est la + rapide pour
"identifier" une classe à partir d'un pointeur sur la classe
de base
La meilleur façon, c'est de ne pas avoir besoin de les
identifier. En général, s'il faut savoir la classe dérivée à
partir d'un pointeur à la classe de base, il y a quelque chose
qui ne colle pas. (Il y a des exceptions, évidemment.)
Base *ptr=new Derivee1 ;
choix 1 :
if (ptr->id()==ID1)
...
ou choix2
if (dynamic_cast<Derivee1*>(ptr))
...
A priori, les deux sont équivalentes (et la seconde présente
l'avantage d'éviter l'oubli de la redéfinition de méthode
virtuelle...)
Tout dépend du compilateur, mais en général, le dynamic_cast est
plus lourd et plus cher que l'appel d'une fonction viruelle.
--
James Kanze (GABI Software) email:james.kanze@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
J'ai une hiérarchie de classes dérivées d'une même classe de base Base, pour simplifier, quelque chose qui ressemble à ce qui suit :
class Base { enum ID { ID1,ID2}; virtual ID id() { throw; } };
class Derivee1 : public Base { virtual ID id() { return ID1; } };
class Derivee2 : public Base { virtual ID id() { return ID2; } };
Dans mon application, la performance est importante => je voudrais savoir quelle méthode est la + rapide pour "identifier" une classe à partir d'un pointeur sur la classe de base
La meilleur façon, c'est de ne pas avoir besoin de les identifier. En général, s'il faut savoir la classe dérivée à partir d'un pointeur à la classe de base, il y a quelque chose qui ne colle pas. (Il y a des exceptions, évidemment.)
Base *ptr=new Derivee1 ;
choix 1 : if (ptr->id()==ID1) ... ou choix2 if (dynamic_cast<Derivee1*>(ptr)) ...
A priori, les deux sont équivalentes (et la seconde présente l'avantage d'éviter l'oubli de la redéfinition de méthode virtuelle...)
Tout dépend du compilateur, mais en général, le dynamic_cast est plus lourd et plus cher que l'appel d'une fonction viruelle.
-- James Kanze (GABI Software) email: Conseils en informatique orientée objet/ Beratung in objektorientierter Datenverarbeitung 9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Marc G
> La meilleur façon, c'est de ne pas avoir besoin de les identifier. En général, s'il faut savoir la classe dérivée à partir d'un pointeur à la classe de base, il y a quelque chose qui ne colle pas. (Il y a des exceptions, évidemment.)
pour cette fois, je suis dans une exception. le dynamic_cast peut avoir l'"avantage" d'être utilisable aux niveaux intermédiaires... par exemple, si je dérive une classe Derivee11 de Derivee1, il marche toujours...(mais ça peut aussi poser pb) => ça dépend vraiment de ce qu'on veut faire avec.... j'imagine bien le dynamic_cast implémenté comme une fonction virtuelle qui retourne la valeur de la fonction de la classe parent immédiat si le test échoue (donc on balaie du dernier niveau à la classe de base). Est-ce bien le cas ?... Marc
> La meilleur façon, c'est de ne pas avoir besoin de les
identifier. En général, s'il faut savoir la classe dérivée à
partir d'un pointeur à la classe de base, il y a quelque chose
qui ne colle pas. (Il y a des exceptions, évidemment.)
pour cette fois, je suis dans une exception.
le dynamic_cast peut avoir l'"avantage" d'être utilisable aux niveaux
intermédiaires...
par exemple, si je dérive une classe Derivee11 de Derivee1, il marche
toujours...(mais ça peut aussi poser pb)
=> ça dépend vraiment de ce qu'on veut faire avec....
j'imagine bien le dynamic_cast implémenté comme une fonction virtuelle qui
retourne la valeur de la fonction de la classe parent immédiat si le test
échoue
(donc on balaie du dernier niveau à la classe de base). Est-ce bien le cas
?...
Marc
> La meilleur façon, c'est de ne pas avoir besoin de les identifier. En général, s'il faut savoir la classe dérivée à partir d'un pointeur à la classe de base, il y a quelque chose qui ne colle pas. (Il y a des exceptions, évidemment.)
pour cette fois, je suis dans une exception. le dynamic_cast peut avoir l'"avantage" d'être utilisable aux niveaux intermédiaires... par exemple, si je dérive une classe Derivee11 de Derivee1, il marche toujours...(mais ça peut aussi poser pb) => ça dépend vraiment de ce qu'on veut faire avec.... j'imagine bien le dynamic_cast implémenté comme une fonction virtuelle qui retourne la valeur de la fonction de la classe parent immédiat si le test échoue (donc on balaie du dernier niveau à la classe de base). Est-ce bien le cas ?... Marc
Michael Doubez
On 29 juil, 22:11, "Marc G" wrote:
> Pour ne pas oublier de redéfinir la méthode virtuelle tu peux aussi la > rendre virtuelle pure.
oui, c'est certainement ce qu'il faut faire... Je viens d'essayer et l'appel de la méthode virtuelle semble nettement plus rapide (environ 7 fois + sur BCB). Je ne comprends pas trop pourquoi mais bon, puisque c'est comme ça...
Ca depends peut être du niveau d'optimisation demandé et je ne sais pas si il y a eu beaucoup d'effort sur l'optimisation du dynamic_cast<> (), il est rarement utilisé et rarement pour de bonne raisons.
En fait je connais le mécanisme d'implémentation des tables virtuelle s mais pas celui des dynamic_cast... (peut-être qu'il s'appuie sur une fonction virtuelle d'identification justement, d'où le temps + élevé ?) Si quelqu'un en sait plus...
Il utilise les RTTI de l'objet pointé pour determiné si il peut être casté. En pratique, il doit s'agir d'un lookup dans une table. Je suppose qu'il serait possible pour le compilateur d'optimiser dans des cas simples (pas d'héritage multiple) pour faire un minimum de check mais je suppose qu'un mécanisme général est plutôt utilisé.
Concernant ton problème, si déjà ta classe de base a des enums qui représentent des sous-classes, alors tu a déjà une dépendance circulaire et je suppose que le nombre de classes est stable. Il serait alors envisageable d'utiliser un pattern visitor; c'est ce qui te donnerai le plus de flexibilité (au prix de la dépendance circulaire mais tu l'a déjà).
-- Michael
On 29 juil, 22:11, "Marc G" <mgueg...@metrica.fr> wrote:
> Pour ne pas oublier de redéfinir la méthode virtuelle tu peux aussi la
> rendre virtuelle pure.
oui, c'est certainement ce qu'il faut faire...
Je viens d'essayer et l'appel de la méthode virtuelle semble nettement plus
rapide (environ 7 fois + sur BCB).
Je ne comprends pas trop pourquoi mais bon, puisque c'est comme ça...
Ca depends peut être du niveau d'optimisation demandé et je ne sais
pas si il y a eu beaucoup d'effort sur l'optimisation du dynamic_cast<>
(), il est rarement utilisé et rarement pour de bonne raisons.
En fait je connais le mécanisme d'implémentation des tables virtuelle s mais
pas celui des dynamic_cast...
(peut-être qu'il s'appuie sur une fonction virtuelle d'identification
justement, d'où le temps + élevé ?)
Si quelqu'un en sait plus...
Il utilise les RTTI de l'objet pointé pour determiné si il peut être
casté. En pratique, il doit s'agir d'un lookup dans une table.
Je suppose qu'il serait possible pour le compilateur d'optimiser dans
des cas simples (pas d'héritage multiple) pour faire un minimum de
check mais je suppose qu'un mécanisme général est plutôt utilisé.
Concernant ton problème, si déjà ta classe de base a des enums qui
représentent des sous-classes, alors tu a déjà une dépendance
circulaire et je suppose que le nombre de classes est stable. Il
serait alors envisageable d'utiliser un pattern visitor; c'est ce qui
te donnerai le plus de flexibilité (au prix de la dépendance
circulaire mais tu l'a déjà).
> Pour ne pas oublier de redéfinir la méthode virtuelle tu peux aussi la > rendre virtuelle pure.
oui, c'est certainement ce qu'il faut faire... Je viens d'essayer et l'appel de la méthode virtuelle semble nettement plus rapide (environ 7 fois + sur BCB). Je ne comprends pas trop pourquoi mais bon, puisque c'est comme ça...
Ca depends peut être du niveau d'optimisation demandé et je ne sais pas si il y a eu beaucoup d'effort sur l'optimisation du dynamic_cast<> (), il est rarement utilisé et rarement pour de bonne raisons.
En fait je connais le mécanisme d'implémentation des tables virtuelle s mais pas celui des dynamic_cast... (peut-être qu'il s'appuie sur une fonction virtuelle d'identification justement, d'où le temps + élevé ?) Si quelqu'un en sait plus...
Il utilise les RTTI de l'objet pointé pour determiné si il peut être casté. En pratique, il doit s'agir d'un lookup dans une table. Je suppose qu'il serait possible pour le compilateur d'optimiser dans des cas simples (pas d'héritage multiple) pour faire un minimum de check mais je suppose qu'un mécanisme général est plutôt utilisé.
Concernant ton problème, si déjà ta classe de base a des enums qui représentent des sous-classes, alors tu a déjà une dépendance circulaire et je suppose que le nombre de classes est stable. Il serait alors envisageable d'utiliser un pattern visitor; c'est ce qui te donnerai le plus de flexibilité (au prix de la dépendance circulaire mais tu l'a déjà).
-- Michael
James Kanze
On Jul 30, 9:24 am, Michael Doubez wrote:
On 29 juil, 22:11, "Marc G" wrote:
[...]
> En fait je connais le mécanisme d'implémentation des tables > virtuelles mais pas celui des dynamic_cast... > (peut-être qu'il s'appuie sur une fonction virtuelle > d'identification justement, d'où le temps + élevé ?) Si > quelqu'un en sait plus...
Il utilise les RTTI de l'objet pointé pour determiné si il peut être casté. En pratique, il doit s'agir d'un lookup dans une table. Je suppose qu'il serait possible pour le compilateur d'optimiser dans des cas simples (pas d'héritage multiple) pour faire un minimum de check mais je suppose qu'un mécanisme général est plutôt utilisé.
En général, le dynamic_cast est plus lent parce qu'il doit considérer plus d'altérnatifs. Quand on appelle une fonction virtuelle, il y a toujours exactement une seul résolution possible, et il y a toujours une résolution. Tandis qu'on peut faire un dynamic_cast à à peu près n'importe quoi, et il peut échouer. Le résultat, c'est que quand on appelle une fonction virtuelle, c'est en gros la lecture d'une adresse à une adresse donnée, tandis que le dynamic_cast doit, effectivement faire une recherche dans un tableau, en tenant compte de ce que ce qu'il cherche ne s'y trouve peut-être pas.
-- James Kanze (GABI Software) email: Conseils en informatique orientée objet/ Beratung in objektorientierter Datenverarbeitung 9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
On Jul 30, 9:24 am, Michael Doubez <michael.dou...@free.fr> wrote:
On 29 juil, 22:11, "Marc G" <mgueg...@metrica.fr> wrote:
[...]
> En fait je connais le mécanisme d'implémentation des tables
> virtuelles mais pas celui des dynamic_cast...
> (peut-être qu'il s'appuie sur une fonction virtuelle
> d'identification justement, d'où le temps + élevé ?) Si
> quelqu'un en sait plus...
Il utilise les RTTI de l'objet pointé pour determiné si il
peut être casté. En pratique, il doit s'agir d'un lookup dans
une table. Je suppose qu'il serait possible pour le
compilateur d'optimiser dans des cas simples (pas d'héritage
multiple) pour faire un minimum de check mais je suppose qu'un
mécanisme général est plutôt utilisé.
En général, le dynamic_cast est plus lent parce qu'il doit
considérer plus d'altérnatifs. Quand on appelle une fonction
virtuelle, il y a toujours exactement une seul résolution
possible, et il y a toujours une résolution. Tandis qu'on peut
faire un dynamic_cast à à peu près n'importe quoi, et il peut
échouer. Le résultat, c'est que quand on appelle une fonction
virtuelle, c'est en gros la lecture d'une adresse à une adresse
donnée, tandis que le dynamic_cast doit, effectivement faire une
recherche dans un tableau, en tenant compte de ce que ce qu'il
cherche ne s'y trouve peut-être pas.
--
James Kanze (GABI Software) email:james.kanze@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
> En fait je connais le mécanisme d'implémentation des tables > virtuelles mais pas celui des dynamic_cast... > (peut-être qu'il s'appuie sur une fonction virtuelle > d'identification justement, d'où le temps + élevé ?) Si > quelqu'un en sait plus...
Il utilise les RTTI de l'objet pointé pour determiné si il peut être casté. En pratique, il doit s'agir d'un lookup dans une table. Je suppose qu'il serait possible pour le compilateur d'optimiser dans des cas simples (pas d'héritage multiple) pour faire un minimum de check mais je suppose qu'un mécanisme général est plutôt utilisé.
En général, le dynamic_cast est plus lent parce qu'il doit considérer plus d'altérnatifs. Quand on appelle une fonction virtuelle, il y a toujours exactement une seul résolution possible, et il y a toujours une résolution. Tandis qu'on peut faire un dynamic_cast à à peu près n'importe quoi, et il peut échouer. Le résultat, c'est que quand on appelle une fonction virtuelle, c'est en gros la lecture d'une adresse à une adresse donnée, tandis que le dynamic_cast doit, effectivement faire une recherche dans un tableau, en tenant compte de ce que ce qu'il cherche ne s'y trouve peut-être pas.
-- James Kanze (GABI Software) email: Conseils en informatique orientée objet/ Beratung in objektorientierter Datenverarbeitung 9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
James Kanze
On Jul 29, 10:26 pm, "Marc G" wrote:
> La meilleur façon, c'est de ne pas avoir besoin de les > identifier. En général, s'il faut savoir la classe dérivée à > partir d'un pointeur à la classe de base, il y a quelque > chose qui ne colle pas. (Il y a des exceptions, évidemment.)
pour cette fois, je suis dans une exception. le dynamic_cast peut avoir l'"avantage" d'être utilisable aux niveaux intermédiaires... par exemple, si je dérive une classe Derivee11 de Derivee1, il marche toujours...(mais ça peut aussi poser pb) => ça dépend vraiment de ce qu'on veut faire avec....
Je n'y ai rien compris, mais en général, quand il y a dynamic_cast dans tous les sens, c'est qu'on n'a pas prévu ce qu'il fallait dans la classe de base.
j'imagine bien le dynamic_cast implémenté comme une fonction virtuelle qui retourne la valeur de la fonction de la classe parent immédiat si le test échoue (donc on balaie du dernier niveau à la classe de base). Est-ce bien le cas ?...
Dans les implémentations classique, le dynamic_cast renvoie effectivement à un pointeur dans le vtbl. Un pointeur à des données, en revanche, et non à une fonction (mais on pourrait aussi l'implémenter avec une fonction différente par classe). Ensuite, le code recherche la classe voulue dans ces données.
-- James Kanze (GABI Software) email: Conseils en informatique orientée objet/ Beratung in objektorientierter Datenverarbeitung 9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
On Jul 29, 10:26 pm, "Marc G" <mgueg...@metrica.fr> wrote:
> La meilleur façon, c'est de ne pas avoir besoin de les
> identifier. En général, s'il faut savoir la classe dérivée à
> partir d'un pointeur à la classe de base, il y a quelque
> chose qui ne colle pas. (Il y a des exceptions, évidemment.)
pour cette fois, je suis dans une exception.
le dynamic_cast peut avoir l'"avantage" d'être utilisable aux
niveaux intermédiaires...
par exemple, si je dérive une classe Derivee11 de Derivee1, il
marche toujours...(mais ça peut aussi poser pb)
=> ça dépend vraiment de ce qu'on veut faire avec....
Je n'y ai rien compris, mais en général, quand il y a
dynamic_cast dans tous les sens, c'est qu'on n'a pas prévu ce
qu'il fallait dans la classe de base.
j'imagine bien le dynamic_cast implémenté comme une fonction
virtuelle qui retourne la valeur de la fonction de la classe
parent immédiat si le test échoue (donc on balaie du dernier
niveau à la classe de base). Est-ce bien le cas ?...
Dans les implémentations classique, le dynamic_cast renvoie
effectivement à un pointeur dans le vtbl. Un pointeur à des
données, en revanche, et non à une fonction (mais on pourrait
aussi l'implémenter avec une fonction différente par classe).
Ensuite, le code recherche la classe voulue dans ces données.
--
James Kanze (GABI Software) email:james.kanze@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
> La meilleur façon, c'est de ne pas avoir besoin de les > identifier. En général, s'il faut savoir la classe dérivée à > partir d'un pointeur à la classe de base, il y a quelque > chose qui ne colle pas. (Il y a des exceptions, évidemment.)
pour cette fois, je suis dans une exception. le dynamic_cast peut avoir l'"avantage" d'être utilisable aux niveaux intermédiaires... par exemple, si je dérive une classe Derivee11 de Derivee1, il marche toujours...(mais ça peut aussi poser pb) => ça dépend vraiment de ce qu'on veut faire avec....
Je n'y ai rien compris, mais en général, quand il y a dynamic_cast dans tous les sens, c'est qu'on n'a pas prévu ce qu'il fallait dans la classe de base.
j'imagine bien le dynamic_cast implémenté comme une fonction virtuelle qui retourne la valeur de la fonction de la classe parent immédiat si le test échoue (donc on balaie du dernier niveau à la classe de base). Est-ce bien le cas ?...
Dans les implémentations classique, le dynamic_cast renvoie effectivement à un pointeur dans le vtbl. Un pointeur à des données, en revanche, et non à une fonction (mais on pourrait aussi l'implémenter avec une fonction différente par classe). Ensuite, le code recherche la classe voulue dans ces données.
-- James Kanze (GABI Software) email: Conseils en informatique orientée objet/ Beratung in objektorientierter Datenverarbeitung 9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34