Matthieu Moy wrote:Bonjour,
J'ai une arborescence de classe qui ressemble à ça (Pour ceux
qui connaissent, c'est un signal SystemC) :
If
^
|
A<T> B
^ ^
| |
`--.--'
|
C<T>
(If est une interface)
Je ne comprends pas bien pourquoi tu as vraiment un probleme, car
comment se fait-il que tu ne puisse pas convertir successivement a
l'aide de static_cast vers A<T>, car ce parametre template, tu dois
bien l'avoir?
Matthieu Moy wrote:
Bonjour,
J'ai une arborescence de classe qui ressemble à ça (Pour ceux
qui connaissent, c'est un signal SystemC) :
If
^
|
A<T> B
^ ^
| |
`--.--'
|
C<T>
(If est une interface)
Je ne comprends pas bien pourquoi tu as vraiment un probleme, car
comment se fait-il que tu ne puisse pas convertir successivement a
l'aide de static_cast vers A<T>, car ce parametre template, tu dois
bien l'avoir?
Matthieu Moy wrote:Bonjour,
J'ai une arborescence de classe qui ressemble à ça (Pour ceux
qui connaissent, c'est un signal SystemC) :
If
^
|
A<T> B
^ ^
| |
`--.--'
|
C<T>
(If est une interface)
Je ne comprends pas bien pourquoi tu as vraiment un probleme, car
comment se fait-il que tu ne puisse pas convertir successivement a
l'aide de static_cast vers A<T>, car ce parametre template, tu dois
bien l'avoir?
Bonjour,
J'ai une arborescence de classe qui ressemble à ça (Pour ceux qui
connaissent, c'est un signal SystemC) :
If
^
|
A<T> B
^ ^
| |
`--.--'
|
C<T>
(If est une interface)
J'ai un pointeur ptr sur un objet de type B, mais le type du pointeur
est If *. Je veux donc faire un cast.
Si C n'était pas un template, j'aurais bien casté successivement en C
puis en B, mais là, j'ai un template, dont je ne connais pas le type à
ce point du programme.
Si je fais simplement "(B *)ptr", alors "boom", il y a des décallages
d'adresses qui se passent mal, et je récupère un pointeur sur rien du
tout.
Si je fais "dynamic_cast<B *>(ptr)", ça a l'air de bien se passer (GCC
3.2).
Je dis « ça a l'air », mais justement, ce que je voudrais savoir,
c'est si il y a une bonne raison pour que ça se passe bien, et quels
risques je prends à faire ce genre de manips. (En général, ce qui
tourne autour de l'héritage multiple me fait un peu peur !)
Et accessoirement, y a-t-il une autre solution (Changer la hierarchie
de classe n'est pas une option, ce n'est pas du code à moi.) ?
Bonjour,
J'ai une arborescence de classe qui ressemble à ça (Pour ceux qui
connaissent, c'est un signal SystemC) :
If
^
|
A<T> B
^ ^
| |
`--.--'
|
C<T>
(If est une interface)
J'ai un pointeur ptr sur un objet de type B, mais le type du pointeur
est If *. Je veux donc faire un cast.
Si C n'était pas un template, j'aurais bien casté successivement en C
puis en B, mais là, j'ai un template, dont je ne connais pas le type à
ce point du programme.
Si je fais simplement "(B *)ptr", alors "boom", il y a des décallages
d'adresses qui se passent mal, et je récupère un pointeur sur rien du
tout.
Si je fais "dynamic_cast<B *>(ptr)", ça a l'air de bien se passer (GCC
3.2).
Je dis « ça a l'air », mais justement, ce que je voudrais savoir,
c'est si il y a une bonne raison pour que ça se passe bien, et quels
risques je prends à faire ce genre de manips. (En général, ce qui
tourne autour de l'héritage multiple me fait un peu peur !)
Et accessoirement, y a-t-il une autre solution (Changer la hierarchie
de classe n'est pas une option, ce n'est pas du code à moi.) ?
Bonjour,
J'ai une arborescence de classe qui ressemble à ça (Pour ceux qui
connaissent, c'est un signal SystemC) :
If
^
|
A<T> B
^ ^
| |
`--.--'
|
C<T>
(If est une interface)
J'ai un pointeur ptr sur un objet de type B, mais le type du pointeur
est If *. Je veux donc faire un cast.
Si C n'était pas un template, j'aurais bien casté successivement en C
puis en B, mais là, j'ai un template, dont je ne connais pas le type à
ce point du programme.
Si je fais simplement "(B *)ptr", alors "boom", il y a des décallages
d'adresses qui se passent mal, et je récupère un pointeur sur rien du
tout.
Si je fais "dynamic_cast<B *>(ptr)", ça a l'air de bien se passer (GCC
3.2).
Je dis « ça a l'air », mais justement, ce que je voudrais savoir,
c'est si il y a une bonne raison pour que ça se passe bien, et quels
risques je prends à faire ce genre de manips. (En général, ce qui
tourne autour de l'héritage multiple me fait un peu peur !)
Et accessoirement, y a-t-il une autre solution (Changer la hierarchie
de classe n'est pas une option, ce n'est pas du code à moi.) ?
Bonjour,
J'ai une arborescence de classe qui ressemble à ça (Pour ceux qui
connaissent, c'est un signal SystemC) :
If
^
|
A<T> B
^ ^
| |
`--.--'
|
C<T>
(If est une interface)
J'ai un pointeur ptr sur un objet de type B, mais le type du pointeur
est If *. Je veux donc faire un cast.
Si C n'était pas un template, j'aurais bien casté successivement en C
puis en B, mais là, j'ai un template, dont je ne connais pas le type à
ce point du programme.
Si je fais simplement "(B *)ptr", alors "boom", il y a des décallages
d'adresses qui se passent mal, et je récupère un pointeur sur rien du
tout.
Si je fais "dynamic_cast<B *>(ptr)", ça a l'air de bien se passer (GCC
3.2).
Je dis « ça a l'air », mais justement, ce que je voudrais savoir,
c'est si il y a une bonne raison pour que ça se passe bien, et quels
risques je prends à faire ce genre de manips. (En général, ce qui
tourne autour de l'héritage multiple me fait un peu peur !)
Et accessoirement, y a-t-il une autre solution (Changer la hierarchie
de classe n'est pas une option, ce n'est pas du code à moi.) ?
--
Matthieu
Bonjour,
J'ai une arborescence de classe qui ressemble à ça (Pour ceux qui
connaissent, c'est un signal SystemC) :
If
^
|
A<T> B
^ ^
| |
`--.--'
|
C<T>
(If est une interface)
J'ai un pointeur ptr sur un objet de type B, mais le type du pointeur
est If *. Je veux donc faire un cast.
Si C n'était pas un template, j'aurais bien casté successivement en C
puis en B, mais là, j'ai un template, dont je ne connais pas le type à
ce point du programme.
Si je fais simplement "(B *)ptr", alors "boom", il y a des décallages
d'adresses qui se passent mal, et je récupère un pointeur sur rien du
tout.
Si je fais "dynamic_cast<B *>(ptr)", ça a l'air de bien se passer (GCC
3.2).
Je dis « ça a l'air », mais justement, ce que je voudrais savoir,
c'est si il y a une bonne raison pour que ça se passe bien, et quels
risques je prends à faire ce genre de manips. (En général, ce qui
tourne autour de l'héritage multiple me fait un peu peur !)
Et accessoirement, y a-t-il une autre solution (Changer la hierarchie
de classe n'est pas une option, ce n'est pas du code à moi.) ?
--
Matthieu
Bonjour,
J'ai une arborescence de classe qui ressemble à ça (Pour ceux qui
connaissent, c'est un signal SystemC) :
If
^
|
A<T> B
^ ^
| |
`--.--'
|
C<T>
(If est une interface)
J'ai un pointeur ptr sur un objet de type B, mais le type du pointeur
est If *. Je veux donc faire un cast.
Si C n'était pas un template, j'aurais bien casté successivement en C
puis en B, mais là, j'ai un template, dont je ne connais pas le type à
ce point du programme.
Si je fais simplement "(B *)ptr", alors "boom", il y a des décallages
d'adresses qui se passent mal, et je récupère un pointeur sur rien du
tout.
Si je fais "dynamic_cast<B *>(ptr)", ça a l'air de bien se passer (GCC
3.2).
Je dis « ça a l'air », mais justement, ce que je voudrais savoir,
c'est si il y a une bonne raison pour que ça se passe bien, et quels
risques je prends à faire ce genre de manips. (En général, ce qui
tourne autour de l'héritage multiple me fait un peu peur !)
Et accessoirement, y a-t-il une autre solution (Changer la hierarchie
de classe n'est pas une option, ce n'est pas du code à moi.) ?
--
Matthieu
"Matthieu Moy" a écrit dans le message
de news:Bonjour,
J'ai une arborescence de classe qui ressemble à ça (Pour ceux qui
connaissent, c'est un signal SystemC) :
If
^
|
A<T> B
^ ^
| |
`--.--'
|
C<T>
(If est une interface)
J'ai un pointeur ptr sur un objet de type B, mais le type du pointeur
est If *. Je veux donc faire un cast.
Il y a un problème : B n'a aucun rapport avec If. Tu pourrais trantyper en A
ou en C, mais en B ça n'a aucun sens ! Rien n'impose les propriétés et
fonctions de B d'être identiques à celles de If... Donc problème de
conception au départ. Un If* NE PEUT pointer sur un B.
If(virtual) ?
^
|
A<T> B(virtual) ?
^ ^
| |
`--.--X
|
C<T>
If(virtual)
^
|
A<T> B(virtual)
^ ^
| |
`--.--'
|
C<T> X(virtual)
| |
|
K<T>
Si C n'était pas un template, j'aurais bien casté successivement en C
puis en B, mais là, j'ai un template, dont je ne connais pas le type à
ce point du programme.
Si je fais simplement "(B *)ptr", alors "boom", il y a des décallages
d'adresses qui se passent mal, et je récupère un pointeur sur rien du
tout.
Si je fais "dynamic_cast<B *>(ptr)", ça a l'air de bien se passer (GCC
3.2).
Je dis « ça a l'air », mais justement, ce que je voudrais savoir,
c'est si il y a une bonne raison pour que ça se passe bien, et quels
risques je prends à faire ce genre de manips. (En général, ce qui
tourne autour de l'héritage multiple me fait un peu peur !)
Et accessoirement, y a-t-il une autre solution (Changer la hierarchie
de classe n'est pas une option, ce n'est pas du code à moi.) ?
--
Matthieu
"Matthieu Moy" <MatthieuNOSPAM.Moy@imag.fr.invalid> a écrit dans le message
de news:vpqptcxldes.fsf@ecrins.imag.fr...
Bonjour,
J'ai une arborescence de classe qui ressemble à ça (Pour ceux qui
connaissent, c'est un signal SystemC) :
If
^
|
A<T> B
^ ^
| |
`--.--'
|
C<T>
(If est une interface)
J'ai un pointeur ptr sur un objet de type B, mais le type du pointeur
est If *. Je veux donc faire un cast.
Il y a un problème : B n'a aucun rapport avec If. Tu pourrais trantyper en A
ou en C, mais en B ça n'a aucun sens ! Rien n'impose les propriétés et
fonctions de B d'être identiques à celles de If... Donc problème de
conception au départ. Un If* NE PEUT pointer sur un B.
If(virtual) ?
^
|
A<T> B(virtual) ?
^ ^
| |
`--.--X
|
C<T>
If(virtual)
^
|
A<T> B(virtual)
^ ^
| |
`--.--'
|
C<T> X(virtual)
| |
|
K<T>
Si C n'était pas un template, j'aurais bien casté successivement en C
puis en B, mais là, j'ai un template, dont je ne connais pas le type à
ce point du programme.
Si je fais simplement "(B *)ptr", alors "boom", il y a des décallages
d'adresses qui se passent mal, et je récupère un pointeur sur rien du
tout.
Si je fais "dynamic_cast<B *>(ptr)", ça a l'air de bien se passer (GCC
3.2).
Je dis « ça a l'air », mais justement, ce que je voudrais savoir,
c'est si il y a une bonne raison pour que ça se passe bien, et quels
risques je prends à faire ce genre de manips. (En général, ce qui
tourne autour de l'héritage multiple me fait un peu peur !)
Et accessoirement, y a-t-il une autre solution (Changer la hierarchie
de classe n'est pas une option, ce n'est pas du code à moi.) ?
--
Matthieu
"Matthieu Moy" a écrit dans le message
de news:Bonjour,
J'ai une arborescence de classe qui ressemble à ça (Pour ceux qui
connaissent, c'est un signal SystemC) :
If
^
|
A<T> B
^ ^
| |
`--.--'
|
C<T>
(If est une interface)
J'ai un pointeur ptr sur un objet de type B, mais le type du pointeur
est If *. Je veux donc faire un cast.
Il y a un problème : B n'a aucun rapport avec If. Tu pourrais trantyper en A
ou en C, mais en B ça n'a aucun sens ! Rien n'impose les propriétés et
fonctions de B d'être identiques à celles de If... Donc problème de
conception au départ. Un If* NE PEUT pointer sur un B.
If(virtual) ?
^
|
A<T> B(virtual) ?
^ ^
| |
`--.--X
|
C<T>
If(virtual)
^
|
A<T> B(virtual)
^ ^
| |
`--.--'
|
C<T> X(virtual)
| |
|
K<T>
Si C n'était pas un template, j'aurais bien casté successivement en C
puis en B, mais là, j'ai un template, dont je ne connais pas le type à
ce point du programme.
Si je fais simplement "(B *)ptr", alors "boom", il y a des décallages
d'adresses qui se passent mal, et je récupère un pointeur sur rien du
tout.
Si je fais "dynamic_cast<B *>(ptr)", ça a l'air de bien se passer (GCC
3.2).
Je dis « ça a l'air », mais justement, ce que je voudrais savoir,
c'est si il y a une bonne raison pour que ça se passe bien, et quels
risques je prends à faire ce genre de manips. (En général, ce qui
tourne autour de l'héritage multiple me fait un peu peur !)
Et accessoirement, y a-t-il une autre solution (Changer la hierarchie
de classe n'est pas une option, ce n'est pas du code à moi.) ?
--
Matthieu
"Matthieu Moy" a écrit dans le message
de news:Bonjour,
J'ai une arborescence de classe qui ressemble à ça (Pour ceux qui
connaissent, c'est un signal SystemC) :
If
^
|
A<T> B
^ ^
| |
`--.--'
|
C<T>
(If est une interface)
J'ai un pointeur ptr sur un objet de type B, mais le type du pointeur
est If *. Je veux donc faire un cast.
Il y a un problème : B n'a aucun rapport avec If. Tu pourrais trantyper en A
ou en C, mais en B ça n'a aucun sens ! Rien n'impose les propriétés et
fonctions de B d'être identiques à celles de If... Donc problème de
conception au départ. Un If* NE PEUT pointer sur un B.
"Matthieu Moy" <MatthieuNOSPAM.Moy@imag.fr.invalid> a écrit dans le message
de news:vpqptcxldes.fsf@ecrins.imag.fr...
Bonjour,
J'ai une arborescence de classe qui ressemble à ça (Pour ceux qui
connaissent, c'est un signal SystemC) :
If
^
|
A<T> B
^ ^
| |
`--.--'
|
C<T>
(If est une interface)
J'ai un pointeur ptr sur un objet de type B, mais le type du pointeur
est If *. Je veux donc faire un cast.
Il y a un problème : B n'a aucun rapport avec If. Tu pourrais trantyper en A
ou en C, mais en B ça n'a aucun sens ! Rien n'impose les propriétés et
fonctions de B d'être identiques à celles de If... Donc problème de
conception au départ. Un If* NE PEUT pointer sur un B.
"Matthieu Moy" a écrit dans le message
de news:Bonjour,
J'ai une arborescence de classe qui ressemble à ça (Pour ceux qui
connaissent, c'est un signal SystemC) :
If
^
|
A<T> B
^ ^
| |
`--.--'
|
C<T>
(If est une interface)
J'ai un pointeur ptr sur un objet de type B, mais le type du pointeur
est If *. Je veux donc faire un cast.
Il y a un problème : B n'a aucun rapport avec If. Tu pourrais trantyper en A
ou en C, mais en B ça n'a aucun sens ! Rien n'impose les propriétés et
fonctions de B d'être identiques à celles de If... Donc problème de
conception au départ. Un If* NE PEUT pointer sur un B.
Yannick Le goc writes:Matthieu Moy wrote:Bonjour,
J'ai une arborescence de classe qui ressemble à ça (Pour ceux
qui connaissent, c'est un signal SystemC) :
If
^
|
A<T> B
^ ^
| |
`--.--'
|
C<T>
(If est une interface)
[...]
Les structures de données sont construites dans un morceau de code que
je ne maitrise pas. Là où j'interviens, j'ai juste un "If *", et c'est
tout. Le paramètre du template est inconnu, peut varier selon les
execution, et peut être différent à chaque fois en repassant plusieurs
fois sur la même ligne de code :-(.
Et non, mettre des dynamic_cast<> de partout ne m'enchante pas
particulièrement, c'est bien pour ça que je pose la question.
C'est triste, hein ! ;-)
'dynamic_cast' est pourtant bien fait pour des cas comme ça et il
Yannick Le goc <legoc@imag.fr> writes:
Matthieu Moy wrote:
Bonjour,
J'ai une arborescence de classe qui ressemble à ça (Pour ceux
qui connaissent, c'est un signal SystemC) :
If
^
|
A<T> B
^ ^
| |
`--.--'
|
C<T>
(If est une interface)
[...]
Les structures de données sont construites dans un morceau de code que
je ne maitrise pas. Là où j'interviens, j'ai juste un "If *", et c'est
tout. Le paramètre du template est inconnu, peut varier selon les
execution, et peut être différent à chaque fois en repassant plusieurs
fois sur la même ligne de code :-(.
Et non, mettre des dynamic_cast<> de partout ne m'enchante pas
particulièrement, c'est bien pour ça que je pose la question.
C'est triste, hein ! ;-)
'dynamic_cast' est pourtant bien fait pour des cas comme ça et il
Yannick Le goc writes:Matthieu Moy wrote:Bonjour,
J'ai une arborescence de classe qui ressemble à ça (Pour ceux
qui connaissent, c'est un signal SystemC) :
If
^
|
A<T> B
^ ^
| |
`--.--'
|
C<T>
(If est une interface)
[...]
Les structures de données sont construites dans un morceau de code que
je ne maitrise pas. Là où j'interviens, j'ai juste un "If *", et c'est
tout. Le paramètre du template est inconnu, peut varier selon les
execution, et peut être différent à chaque fois en repassant plusieurs
fois sur la même ligne de code :-(.
Et non, mettre des dynamic_cast<> de partout ne m'enchante pas
particulièrement, c'est bien pour ça que je pose la question.
C'est triste, hein ! ;-)
'dynamic_cast' est pourtant bien fait pour des cas comme ça et il
J'ai une arborescence de classe qui ressemble à ça (Pour ceux qui
connaissent, c'est un signal SystemC) :
If
^
|
A<T> B
^ ^
| |
`--.--'
|
C<T>
(If est une interface)
J'ai un pointeur ptr sur un objet de type B, mais le type du pointeur
est If *. Je veux donc faire un cast.
Si C n'était pas un template, j'aurais bien casté successivement en C
puis en B, mais là, j'ai un template, dont je ne connais pas le type à
ce point du programme.
Si je fais simplement "(B *)ptr", alors "boom", il y a des décallages
d'adresses qui se passent mal, et je récupère un pointeur sur rien du
tout.
Si je fais "dynamic_cast<B *>(ptr)", ça a l'air de bien se passer (GCC
3.2).
Je dis « ça a l'air », mais justement, ce que je voudrais savoir,
c'est si il y a une bonne raison pour que ça se passe bien, et quels
risques je prends à faire ce genre de manips. (En général, ce qui
tourne autour de l'héritage multiple me fait un peu peur !)
Et accessoirement, y a-t-il une autre solution (Changer la hierarchie
de classe n'est pas une option, ce n'est pas du code à moi.) ?
J'ai une arborescence de classe qui ressemble à ça (Pour ceux qui
connaissent, c'est un signal SystemC) :
If
^
|
A<T> B
^ ^
| |
`--.--'
|
C<T>
(If est une interface)
J'ai un pointeur ptr sur un objet de type B, mais le type du pointeur
est If *. Je veux donc faire un cast.
Si C n'était pas un template, j'aurais bien casté successivement en C
puis en B, mais là, j'ai un template, dont je ne connais pas le type à
ce point du programme.
Si je fais simplement "(B *)ptr", alors "boom", il y a des décallages
d'adresses qui se passent mal, et je récupère un pointeur sur rien du
tout.
Si je fais "dynamic_cast<B *>(ptr)", ça a l'air de bien se passer (GCC
3.2).
Je dis « ça a l'air », mais justement, ce que je voudrais savoir,
c'est si il y a une bonne raison pour que ça se passe bien, et quels
risques je prends à faire ce genre de manips. (En général, ce qui
tourne autour de l'héritage multiple me fait un peu peur !)
Et accessoirement, y a-t-il une autre solution (Changer la hierarchie
de classe n'est pas une option, ce n'est pas du code à moi.) ?
J'ai une arborescence de classe qui ressemble à ça (Pour ceux qui
connaissent, c'est un signal SystemC) :
If
^
|
A<T> B
^ ^
| |
`--.--'
|
C<T>
(If est une interface)
J'ai un pointeur ptr sur un objet de type B, mais le type du pointeur
est If *. Je veux donc faire un cast.
Si C n'était pas un template, j'aurais bien casté successivement en C
puis en B, mais là, j'ai un template, dont je ne connais pas le type à
ce point du programme.
Si je fais simplement "(B *)ptr", alors "boom", il y a des décallages
d'adresses qui se passent mal, et je récupère un pointeur sur rien du
tout.
Si je fais "dynamic_cast<B *>(ptr)", ça a l'air de bien se passer (GCC
3.2).
Je dis « ça a l'air », mais justement, ce que je voudrais savoir,
c'est si il y a une bonne raison pour que ça se passe bien, et quels
risques je prends à faire ce genre de manips. (En général, ce qui
tourne autour de l'héritage multiple me fait un peu peur !)
Et accessoirement, y a-t-il une autre solution (Changer la hierarchie
de classe n'est pas une option, ce n'est pas du code à moi.) ?
Il y a un problème : B n'a aucun rapport avec If. Tu pourrais trantyper
en A
ou en C, mais en B ça n'a aucun sens ! Rien n'impose les propriétés et
fonctions de B d'être identiques à celles de If... Donc problème de
conception au départ. Un If* NE PEUT pointer sur un B.
Sauf s'il pointe sur un C<T>. C'est un problème de vocabulaire utilisé
dans la damande. On a un pointeur sur If qui pointe en réalité sur un
objet du type C<T>, et on veut retrouver la partie B de cet objet.
Par contre, a moins d'être certain que le pointeur sur If pointe en fait
sur un C<T> (ce qui permettrait de faire un static_cast en C<T> puis un
autre en B (et qui impose donc de connaître T)), un dynamic_cast s'impose.
Voir par exemple www.research.att.com/~bs/performanceTR.pdf pour une
étude plus détaillée des coûts de dynamic_cast.
Et pour finir, un petit extrait de la norme sur dynamic_cast <T> (v),
dans le cas où une vérification au run-time est nécessaire :
The runtime check logically executes as follows:
If, in the most derived object pointed (referred) to by v, v points
(refers) to a public base class subobject of a T object, and if only one
object of type T is derived from the subobject pointed (referred) to
by v, the result is a pointer (an lvalue referring) to that T object.
Otherwise, if v points (refers) to a public base class subobject
of the most derived object, and the type of the most derived object has
an unambiguous public base class of type T, the result is a pointer
(an lvalue referring) to the T subobject of the most derived object.
Otherwise, the runtime check fails.
--
Loïc
Il y a un problème : B n'a aucun rapport avec If. Tu pourrais trantyper
en A
ou en C, mais en B ça n'a aucun sens ! Rien n'impose les propriétés et
fonctions de B d'être identiques à celles de If... Donc problème de
conception au départ. Un If* NE PEUT pointer sur un B.
Sauf s'il pointe sur un C<T>. C'est un problème de vocabulaire utilisé
dans la damande. On a un pointeur sur If qui pointe en réalité sur un
objet du type C<T>, et on veut retrouver la partie B de cet objet.
Par contre, a moins d'être certain que le pointeur sur If pointe en fait
sur un C<T> (ce qui permettrait de faire un static_cast en C<T> puis un
autre en B (et qui impose donc de connaître T)), un dynamic_cast s'impose.
Voir par exemple www.research.att.com/~bs/performanceTR.pdf pour une
étude plus détaillée des coûts de dynamic_cast.
Et pour finir, un petit extrait de la norme sur dynamic_cast <T> (v),
dans le cas où une vérification au run-time est nécessaire :
The runtime check logically executes as follows:
If, in the most derived object pointed (referred) to by v, v points
(refers) to a public base class subobject of a T object, and if only one
object of type T is derived from the subobject pointed (referred) to
by v, the result is a pointer (an lvalue referring) to that T object.
Otherwise, if v points (refers) to a public base class subobject
of the most derived object, and the type of the most derived object has
an unambiguous public base class of type T, the result is a pointer
(an lvalue referring) to the T subobject of the most derived object.
Otherwise, the runtime check fails.
--
Loïc
Il y a un problème : B n'a aucun rapport avec If. Tu pourrais trantyper
en A
ou en C, mais en B ça n'a aucun sens ! Rien n'impose les propriétés et
fonctions de B d'être identiques à celles de If... Donc problème de
conception au départ. Un If* NE PEUT pointer sur un B.
Sauf s'il pointe sur un C<T>. C'est un problème de vocabulaire utilisé
dans la damande. On a un pointeur sur If qui pointe en réalité sur un
objet du type C<T>, et on veut retrouver la partie B de cet objet.
Par contre, a moins d'être certain que le pointeur sur If pointe en fait
sur un C<T> (ce qui permettrait de faire un static_cast en C<T> puis un
autre en B (et qui impose donc de connaître T)), un dynamic_cast s'impose.
Voir par exemple www.research.att.com/~bs/performanceTR.pdf pour une
étude plus détaillée des coûts de dynamic_cast.
Et pour finir, un petit extrait de la norme sur dynamic_cast <T> (v),
dans le cas où une vérification au run-time est nécessaire :
The runtime check logically executes as follows:
If, in the most derived object pointed (referred) to by v, v points
(refers) to a public base class subobject of a T object, and if only one
object of type T is derived from the subobject pointed (referred) to
by v, the result is a pointer (an lvalue referring) to that T object.
Otherwise, if v points (refers) to a public base class subobject
of the most derived object, and the type of the most derived object has
an unambiguous public base class of type T, the result is a pointer
(an lvalue referring) to the T subobject of the most derived object.
Otherwise, the runtime check fails.
--
Loïc
Sauf s'il pointe sur un C<T>. C'est un problème de vocabulaire utilisé
dans la damande. On a un pointeur sur If qui pointe en réalité sur un
objet du type C<T>, et on veut retrouver la partie B de cet objet.
Mais ce n'est pas du tout logique : le pointeur sur If devrait être utilisé
pour les fonctionnalités définies dans If, à savoir l'interface. S'il pointe
sur un C<T> il est effectivement indispensable de connaitre T pour retrouver
les membres de B.
Je pense qu'il y a un pb de conception au départ... Si on a un pointeur de
If, c'est qu'on veut utiliser la partie interface des classes dérivées, pas
des classes n'ayant pas de rapport avec If.
C'est souvent dû à une erreur de conception qu'on utilise un cast.
Sauf s'il pointe sur un C<T>. C'est un problème de vocabulaire utilisé
dans la damande. On a un pointeur sur If qui pointe en réalité sur un
objet du type C<T>, et on veut retrouver la partie B de cet objet.
Mais ce n'est pas du tout logique : le pointeur sur If devrait être utilisé
pour les fonctionnalités définies dans If, à savoir l'interface. S'il pointe
sur un C<T> il est effectivement indispensable de connaitre T pour retrouver
les membres de B.
Je pense qu'il y a un pb de conception au départ... Si on a un pointeur de
If, c'est qu'on veut utiliser la partie interface des classes dérivées, pas
des classes n'ayant pas de rapport avec If.
C'est souvent dû à une erreur de conception qu'on utilise un cast.
Sauf s'il pointe sur un C<T>. C'est un problème de vocabulaire utilisé
dans la damande. On a un pointeur sur If qui pointe en réalité sur un
objet du type C<T>, et on veut retrouver la partie B de cet objet.
Mais ce n'est pas du tout logique : le pointeur sur If devrait être utilisé
pour les fonctionnalités définies dans If, à savoir l'interface. S'il pointe
sur un C<T> il est effectivement indispensable de connaitre T pour retrouver
les membres de B.
Je pense qu'il y a un pb de conception au départ... Si on a un pointeur de
If, c'est qu'on veut utiliser la partie interface des classes dérivées, pas
des classes n'ayant pas de rapport avec If.
C'est souvent dû à une erreur de conception qu'on utilise un cast.
Et si j'vous embête avec tous mes diclaimers, vous le dites ;)
Et si j'vous embête avec tous mes diclaimers, vous le dites ;)
Et si j'vous embête avec tous mes diclaimers, vous le dites ;)