FAQ: Pourquoi dynamic_cast ne fonctionne que si une classe a au moins 1 méthode virtuelle?

StackOverflow https://stackoverflow.com/questions/4227328

  •  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);
Était-ce utile?

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.

scroll top