FAQ: Pourquoi dynamic_cast ne fonctionne que si une classe a au moins 1 méthode virtuelle?
-
26-09-2019 - |
Question
Cela ne compile pas en C ++:
class A
{
};
class B : public A
{
};
...
A *a = new B();
B *b = dynamic_cast<B*>(a);
La solution
Parce que dynamic_cast
ne peut baissés types polymorphes, donc sayeth la norme.
Vous pouvez faire votre polymoprphic de classe en ajoutant un destructor de virtual
à la classe de base. En fait, vous devriez probablement de toute façon (Voir la note). Sinon, si vous essayez de supprimer un objet B
par un pointeur A
, vous aurez evoke Undefined Comportement .
class A
{
public:
virtual ~A() {};
};
et le tour est joué!
Note
Il y a des exceptions à la « règle » au sujet ayant besoin d'un destructeur virtuel dans les types polymorphes.
Une telle exception est lors de l'utilisation boost::shared_ptr
comme l'a souligné Steve Jessop dans les commentaires ci-dessous. Pour plus d'informations sur le moment où vous avez besoin d'un destructeur virtuel, lire Herb Sutter article de.
Autres conseils
Comme l'autre dit:. La norme dit donc
Alors, pourquoi la norme dit?
Parce que si le type est polymorphique il peut (ou est? Question aux gourous standards) soit un type simple. Et pour les types simples, il y a beaucoup d'hypothèses qui viennent de la compatibilité descendante C. L'un d'entre eux est que le type ne se compose que des membres de elle en tant que développeur a déclaré + octets d'alignement nécessaires. Donc, il ne peut y avoir de champs supplémentaires (cachés). Donc, il n'y a pas moyen de stocker dans l'espace de mémoire conservée par A l'information qu'il est vraiment un B.
Ceci est seulement possible quand il est polymorphes comme il est permis d'ajouter ces choses cachées. (Dans la plupart des implémentations cela se fait via le vtable).
De 5.2.7 (cast dynamique):
Le résultat de l'expression
dynamic_cast<T>(v)
est le résultat de convertir l'expression v de type T.[... plusieurs lignes qui se réfèrent à d'autres cas ...]
Sinon c est un pointeur vers un ou d'un lvalue type polymorphe (10.3).
A partir de 10.3 (fonctions virtuelles):
Une classe qui déclare ou hérite d'une fonction virtuelle est appelée classe polymorphique.