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

10 réponses

1 2
Avatar
Fabien SK
Frédéric Mayot wrote:
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 ?


Je ne comprends pas cette ligne:
A* ptr_a = &c;

La classe A n'a rien a voir avec la classe C. Comment tu peux caster un
C* en A* ?

D'autre part, dynamic_cast marche quand tu as au moins une fonction
virtuelle.

Avatar
Frédéric Mayot
La classe A n'a rien a voir avec la classe C. Comment tu peux caster un
C* en A* ?


Pardon, je voulais écrire ceci bien sûr :

template <typename T>
class B : public A {};

Avatar
Frédéric Mayot
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...

Avatar
Benoit Rousseau
Frédéric Mayot wrote:
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...

Parcequ'il ne marche qu'avec des objets polymorphes, et des objets sont

considérés comme polymorphes quand ils ont une fonction virtuelle.


--------------------------------------------
Benoît Rousseau : roussebe at spray dot se
Jouez en programmant : http://realtimebattle.sourceforge.net/


Avatar
Fabien SK
Frédéric Mayot wrote:


La classe A n'a rien a voir avec la classe C. Comment tu peux caster
un C* en A* ?


Pardon, je voulais écrire ceci bien sûr :

template <typename T>
class B : public A {};


Chez moi ça compile avec Visual C++ 6 et gcc 3.3.1 si je mets:

class A{ public: virtual ~A(){} };

ce qui semble logique (voir le message de Benoit).


Avatar
Michel Michaud
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).

--
Michel Michaud
http://www.gdzid.com
FAQ de fr.comp.lang.c++ :
http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ/


Avatar
Gabriel Dos Reis
"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 ?

-- Gaby
Avatar
Michel Michaud
Dans news:, Gabriel Dos
"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 ?


Est-ce que tu dis la même chose que moi : « le code du dynamic_cast
doit pouvoir regarder quelque part pour vérifier la légalité de la
conversion » ? Parce que tu as écrit « Autrement, ... », je me dis
que tu indiques autre chose et tout ce que je pourrais comprendre
c'est que tu doutes de l'intérêt pourtant réel il me semble (en
autant qu'on trouve un intérêt réel à dynamic_cast en général), de :

class A { /*... (rien n'est virtual) */ };
class B : public A { /*...*/ };
class C : public A { /*...*/ };

void F(A* p)
{
// Si on pouvait :
try
{ B* pB= dynamic_cast<B*>(p); /*...*/ }
catch (...)
{ C* pC= dynamic_cast<C*>(p); /*...*/ }
}

Je ne vois pas pourquoi le fait qu'il y ait ou non une fonction
virtuelle dans A peut changer l'intérêt de la chose...

--
Michel Michaud
http://www.gdzid.com
FAQ de fr.comp.lang.c++ :
http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ/




Avatar
kanze
Frédéric Mayot wrote in message
news:<3fdd9c5a$0$17120$...
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...


Parce qu'il y a une vieille règle que tu ne dois pas payé ce qui ne te
sert pas. Or, si une classe à des fonctions virtuelles, l'implémentation
de dynamique_cast coûte une entrée dans le vtbl, plus ses tables à lui ;
c'est un coût supplémentaire assez faible, et surtout per type. En
revanche, si un type n'a pas de fonctions virtuelles, il n'a pas de
vptr. Il faudrait en ajouter. Et ça, c'est un coût par objet -- ça peut
donc revenir très cher.

--
James Kanze GABI Software mailto:
Conseils en informatique orientée objet/ http://www.gabi-soft.fr
Beratung in objektorientierter Datenverarbeitung
11 rue de Rambouillet, 78460 Chevreuse, France, +33 (0)1 30 23 45 16


Avatar
Alain Naigeon
"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.

--

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

1 2