OVH Cloud OVH Cloud

dynamic_cast, polymorphisme et template

15 réponses
Avatar
Frédéric Mayot
Bonjour,

Quelqu'un pourrait-il m'expliquer pourquoi le code suivant ne compile pas ?

class A{};

template <typename T>
class B {};

class C : public B<int> {};

int main(int argc, char** argv)
{
C c;
A* ptr_a = &c;
C* ptr_c = dynamic_cast<C*>(ptr_a); // L1
return 1;
}

Pour qu'il compile j'ai remplacer L1 par un cast sauvage :

C* ptr_c = (C*)(ptr_a);

Comment puis-je faire cela proprement ?

Merci beaucoup.

Fred

5 réponses

1 2
Avatar
Gabriel Dos Reis
"Alain Naigeon" writes:

| "Gabriel Dos Reis" a écrit dans le message
| news:
| > "Michel Michaud" writes:
| >
| > | Dans news:3fdd9c5a$0$17120$, Frédéric
| > | >> D'autre part, dynamic_cast marche quand tu as au moins une fonction
| > | >> virtuelle.
| > | >
| > | > Il y a une raison à cela ? Je ne comprends pas trop pourquoi...
| > |
| > | Mécaniquement, c'est que le code du dynamic_cast doit pouvoir
| > | regarder quelque part pour vérifier la légalité de la conversion
| > | que tu demandes (sinon tu peux prendre un static_cast). Et c'est
| > | dans l'équivalent de la v-table que l'information sera mise et
| > | il n'y de v-table que pour les classes ayant un semblant de
| > | polymorphisme (i.e. au moins une fonction virtuelle). Si on avait
| > | permis de faire dynamic_cast sur n'importe quelle classe, donc
| > | mettre l'information dans toutes les classes (et struct), on aurait
| > | perdu la compatibilité C (POD).
| >
| > Autrement, on peut la question suivante :
| >
| > Qu'est-ce que cela veut dire de faire un cast dynamique lorsqu'il
| > n'y a aucune chance que le type dynamique de l'objet pointé ou référé
| > soit différent de ce que donne une analyse statique basé sur le
| > type du pointeur ou de la réféerence ?
|
| En exprimant les choses comme ci-dessus, il est tout de même
| facile de trouver une réponse : fonction constante.

Je ne comprends pas la réponse. Dis-moi en un peu plus.

-- Gaby
Avatar
Alain Naigeon
"Gabriel Dos Reis" a écrit dans le message
news:
"Alain Naigeon" writes:

| "Gabriel Dos Reis" a écrit dans le
message

| news:
| > "Michel Michaud" writes:
| >
| > | Dans news:3fdd9c5a$0$17120$, Frédéric
| > | >> D'autre part, dynamic_cast marche quand tu as au moins une
fonction

| > | >> virtuelle.
| > | >
| > | > Il y a une raison à cela ? Je ne comprends pas trop pourquoi...
| > |
| > | Mécaniquement, c'est que le code du dynamic_cast doit pouvoir
| > | regarder quelque part pour vérifier la légalité de la conversion
| > | que tu demandes (sinon tu peux prendre un static_cast). Et c'est
| > | dans l'équivalent de la v-table que l'information sera mise et
| > | il n'y de v-table que pour les classes ayant un semblant de
| > | polymorphisme (i.e. au moins une fonction virtuelle). Si on avait
| > | permis de faire dynamic_cast sur n'importe quelle classe, donc
| > | mettre l'information dans toutes les classes (et struct), on aurait
| > | perdu la compatibilité C (POD).
| >
| > Autrement, on peut la question suivante :
| >
| > Qu'est-ce que cela veut dire de faire un cast dynamique lorsqu'il
| > n'y a aucune chance que le type dynamique de l'objet pointé ou
référé

| > soit différent de ce que donne une analyse statique basé sur le
| > type du pointeur ou de la réféerence ?
|
| En exprimant les choses comme ci-dessus, il est tout de même
| facile de trouver une réponse : fonction constante.


Eh bien : la première idée qui vient en réponse au dernier paragraphe,
c'est : lorsque le type est connu à l'avance, le dynamic_cast pourrait
avoir la politesse de renvoyer identiquement ce type, au lieu de faire
"bêtement" une erreur. On peut, à la rigueur, envisager un warning
sur l'inefficacité (?) de cet emploi, mais je ne vois pas pour quelle
raison le refuser..?

Je ne comprends pas la réponse. Dis-moi en un peu plus.
Tu vois maintenant ce que tu exiges de nous, parfois :-)


[en te paraphrasant : qu'est-ce que ça veut dire de définir f(x)
pour tout x dans D, alors que, cette fonction étant constante,
il n'y a aucune chance pour qu'elle vaille jamais autre chose
que f(x0) ?]

--

Français *==> "Musique renaissance" <==* English
midi - facsimiles - ligatures - mensuration
http://anaigeon.free.fr | http://www.medieval.org/emfaq/anaigeon/
Alain Naigeon - - Strasbourg, France

Avatar
Gabriel Dos Reis
"Alain Naigeon" writes:

| "Gabriel Dos Reis" a écrit dans le message
| news:
| > "Alain Naigeon" writes:
| >
| > | "Gabriel Dos Reis" a écrit dans le
| message
| > | news:
| > | > "Michel Michaud" writes:
| > | >
| > | > | Dans news:3fdd9c5a$0$17120$, Frédéric
| > | > | >> D'autre part, dynamic_cast marche quand tu as au moins une
| fonction
| > | > | >> virtuelle.
| > | > | >
| > | > | > Il y a une raison à cela ? Je ne comprends pas trop pourquoi...
| > | > |
| > | > | Mécaniquement, c'est que le code du dynamic_cast doit pouvoir
| > | > | regarder quelque part pour vérifier la légalité de la conversion
| > | > | que tu demandes (sinon tu peux prendre un static_cast). Et c'est
| > | > | dans l'équivalent de la v-table que l'information sera mise et
| > | > | il n'y de v-table que pour les classes ayant un semblant de
| > | > | polymorphisme (i.e. au moins une fonction virtuelle). Si on avait
| > | > | permis de faire dynamic_cast sur n'importe quelle classe, donc
| > | > | mettre l'information dans toutes les classes (et struct), on aurait
| > | > | perdu la compatibilité C (POD).
| > | >
| > | > Autrement, on peut la question suivante :
| > | >
| > | > Qu'est-ce que cela veut dire de faire un cast dynamique lorsqu'il
| > | > n'y a aucune chance que le type dynamique de l'objet pointé ou
| référé
| > | > soit différent de ce que donne une analyse statique basé sur le
| > | > type du pointeur ou de la réféerence ?
| > |
| > | En exprimant les choses comme ci-dessus, il est tout de même
| > | facile de trouver une réponse : fonction constante.
|
| Eh bien : la première idée qui vient en réponse au dernier paragraphe,
| c'est : lorsque le type est connu à l'avance, le dynamic_cast pourrait
| avoir la politesse de renvoyer identiquement ce type, au lieu de faire
| "bêtement" une erreur.

Mais, ce n'est pas ce qu'on appelle une fonction constante ; tout
au plus, ce serait la fonction identité sur ce sous-ensemble là ;-)

| On peut, à la rigueur, envisager un warning
| sur l'inefficacité (?) de cet emploi, mais je ne vois pas pour quelle
| raison le refuser..?

(1) la norme ne définit pas de warning. Elle définit ce qu'elle
appelle un diagnstic. Si elle demander une diagnostic, c'est
qu'elle pense que la construction n'est pas valide.

(2) c'est déjà le boulot de static_cast -- on peut arguer que les
deux opérateurs ont des sémantiques qui se recouvrent des fois,
mais vois le point suivant ;

(3) dynamic_cast est vraiment conçu pour s'occuper des cast pour des
objets polymorphes ; s'il est utilisé pour des objets non
polymorphes, il y a erreur de « type ». C'est un critère de
conception, le but aboué étant de minimiser le plus possible, le
recours aux casts (ainsi éviter « bof, le compilateur fera
l'identité ici, donc c'est pas la même de se casser la tête pour
un design propre de mon programme »)

| > Je ne comprends pas la réponse. Dis-moi en un peu plus.
| Tu vois maintenant ce que tu exiges de nous, parfois :-)

Hmm, tu es scientifique ; tu sais ce que c'est :-)

| [en te paraphrasant : qu'est-ce que ça veut dire de définir f(x)
| pour tout x dans D, alors que, cette fonction étant constante,
| il n'y a aucune chance pour qu'elle vaille jamais autre chose
| que f(x0) ?]

C'est vraiment une paraphrase ça ?

-- Gaby
Avatar
Alain Naigeon
"Gabriel Dos Reis" a écrit dans le message
news:
"Alain Naigeon" writes:

| "Gabriel Dos Reis" a écrit dans le
message

| news:
| > | > Qu'est-ce que cela veut dire de faire un cast dynamique
lorsqu'il

| > | > n'y a aucune chance que le type dynamique de l'objet pointé ou
| référé
| > | > soit différent de ce que donne une analyse statique basé sur le
| > | > type du pointeur ou de la réféerence ?
| > |
| > | En exprimant les choses comme ci-dessus, il est tout de même
| > | facile de trouver une réponse : fonction constante.
|
| Eh bien : la première idée qui vient en réponse au dernier paragraphe,
| c'est : lorsque le type est connu à l'avance, le dynamic_cast pourrait
| avoir la politesse de renvoyer identiquement ce type, au lieu de faire
| "bêtement" une erreur.

Mais, ce n'est pas ce qu'on appelle une fonction constante ; tout
au plus, ce serait la fonction identité sur ce sous-ensemble là ;-)


Ok, "tout au plus" est juste suffisant, donc tu as raison ;-)


| On peut, à la rigueur, envisager un warning
| sur l'inefficacité (?) de cet emploi, mais je ne vois pas pour quelle
| raison le refuser..?

(1) la norme ne définit pas de warning. Elle définit ce qu'elle
appelle un diagnstic. Si elle demander une diagnostic, c'est
qu'elle pense que la construction n'est pas valide.


Euh, appelle ça comme tu veux (ou comme Elle veut, la norme),
m'enfin... un truc qui émet "conversion may loose digits" c'est
pas franchement invalide, non ?

(2) c'est déjà le boulot de static_cast -- on peut arguer que les
deux opérateurs ont des sémantiques qui se recouvrent des fois,
mais vois le point suivant ;

(3) dynamic_cast est vraiment conçu pour s'occuper des cast pour des
objets polymorphes ; s'il est utilisé pour des objets non
polymorphes, il y a erreur de « type ». C'est un critère de
conception, le but aboué étant de minimiser le plus possible, le
recours aux casts (ainsi éviter « bof, le compilateur fera
l'identité ici, donc c'est pas la même de se casser la tête pour
un design propre de mon programme »)


D'accord, c'est une interdiction pédagogique. C'est ton analyse,
ou est-ce que tu as vraiment des infos comme quoi c'est la raison
de ceux qui ont prévu les choses ainsi ?


| > Je ne comprends pas la réponse. Dis-moi en un peu plus.
| Tu vois maintenant ce que tu exiges de nous, parfois :-)

Hmm, tu es scientifique ; tu sais ce que c'est :-)


Je fus, je fus...

| [en te paraphrasant : qu'est-ce que ça veut dire de définir f(x)
| pour tout x dans D, alors que, cette fonction étant constante,
| il n'y a aucune chance pour qu'elle vaille jamais autre chose
| que f(x0) ?]

C'est vraiment une paraphrase ça ?


Bon écoute, je n'ai plus les citations exactes sous les yeux, et j'ai
un retard de courrier monstrueux, alors, comme je sens une envie
de me répondre "non" si je dis "oui", je passe mon tour :-)

--

Français *==> "Musique renaissance" <==* English
midi - facsimiles - ligatures - mensuration
http://anaigeon.free.fr | http://www.medieval.org/emfaq/anaigeon/
Alain Naigeon - - Strasbourg, France

Avatar
Gabriel Dos Reis
"Alain Naigeon" writes:

| > | On peut, à la rigueur, envisager un warning
| > | sur l'inefficacité (?) de cet emploi, mais je ne vois pas pour quelle
| > | raison le refuser..?
| >
| > (1) la norme ne définit pas de warning. Elle définit ce qu'elle
| > appelle un diagnstic. Si elle demander une diagnostic, c'est
| > qu'elle pense que la construction n'est pas valide.
|
| Euh, appelle ça comme tu veux (ou comme Elle veut, la norme),
| m'enfin... un truc qui émet "conversion may loose digits" c'est
| pas franchement invalide, non ?

Peu importe. Est-ce un diagnostic? Oui, donc, ...
(La norme n'a jamais requis qu'un diagnostic devait être
compréhensible, ni facilement lisible).

| > (2) c'est déjà le boulot de static_cast -- on peut arguer que les
| > deux opérateurs ont des sémantiques qui se recouvrent des fois,
| > mais vois le point suivant ;
| >
| > (3) dynamic_cast est vraiment conçu pour s'occuper des cast pour des
| > objets polymorphes ; s'il est utilisé pour des objets non
| > polymorphes, il y a erreur de « type ». C'est un critère de
| > conception, le but aboué étant de minimiser le plus possible, le
| > recours aux casts (ainsi éviter « bof, le compilateur fera
| > l'identité ici, donc c'est pas la même de se casser la tête pour
| > un design propre de mon programme »)
|
| D'accord, c'est une interdiction pédagogique.

Je ne sais pas si c'est une interdiction pédagogique ou une incitation
active à éviter les « sloppy codes ».

| C'est ton analyse,
| ou est-ce que tu as vraiment des infos comme quoi c'est la raison
| de ceux qui ont prévu les choses ainsi ?

Tu disposes de moyens assez simples pour vérifier si mes allégations
ont quelque rapport avec les critères de conception de
dynamic_cast<>:
(1) lire le chapitre 14 de D&E, pp 305--336;
(2) demander à l'auteur principal de dynamic_cast<>, qui se trouve
être également l'auteur du bouquin cité au (1).
Il n'y a pas d'excuse pour le (2) si tu ne peux pas faire le (1).

-- Gaby
1 2