web-dev-qa-db-fra.com

Vous ne pouvez pas abaisser parce que la classe n'est pas polymorphe?

Est-il possible d'avoir un héritage sans méthodes virtuelles? Le compilateur dit que le code suivant n'est pas polymorphe.

Exemple:

Class A(){
    int a;
    int getA(){return a;};
}


Class B(): A(){
    int b;
    int getB(){return b;};
}

Dans une autre classe, nous essayons de passer d'un objet A à un objet B:

 A *a;
 B *b = dynamic_cast<B*>(a)

mais cela donne l'erreur suivante:

 cannot dynamic_cast ... (source type is polymorphic)
42
wfbarksdale

Nonobstant les erreurs de syntaxe, vous ne pouvez pas dynamic_cast un type non polymorphe. static_cast est la distribution que vous utiliseriez dans ce cas, si vous savez qu'il s'agit en fait d'un objet du type cible.

La raison pour laquelle: static_cast le compilateur effectue-t-il une vérification au moment de la compilation "L'entrée peut-elle être convertie en sortie?" Cela peut être utilisé dans les cas où vous effectuez une conversion vers le haut ou vers le bas d'une hiérarchie d'héritage de pointeurs (ou références). Mais la vérification n'est effectuée qu'au moment de la compilation et le compilateur suppose que vous savez ce que vous faites.

dynamic_cast ne peut être utilisé que dans le cas d'un pointeur ou d'un transtypage de référence, et en plus de la vérification du temps de compilation, il effectue une vérification supplémentaire du temps d'exécution que le transtypage est légal. Il nécessite que la classe en question ait au moins 1 méthode virtuelle, ce qui permet au compilateur (s'il prend en charge RTTI) d'effectuer cette vérification supplémentaire. Cependant, si le type en question n'a aucune méthode virtuelle, il ne peut pas être utilisé.

Le cas le plus simple, et probablement utile si vous passez des pointeurs comme celui-ci, est d'envisager de rendre virtuel le destructeur de la classe de base. En plus de vous permettre d'utiliser la conversion dynamique, il permet également d'appeler les destructeurs appropriés lorsqu'un pointeur de classe de base est supprimé.

69
Dave S

Vous avez besoin d'au moins une méthode virtuelle dans une classe pour que run-time type information (RTTI) applique correctement l'opérateur dynamic_cast.

26
tenorsax

rendez juste un destructeur virtuel (faites toujours pour n'importe quelle classe juste pour la sécurité).

13
user993954

oui, dynamic_cast pour les types non polymorphes n'est pas autorisé. La classe de base doit avoir au moins une méthode virtuelle. Alors seulement, cette classe peut être appelée polymorphe.

Cet article explique un exemple similaire: http://www.cplusplus.com/doc/tutorial/typecasting/

4
Murali Krishna
A a;
B *b = dynamic_cast<B*>(a)

Ici, a est un objet et b est un pointeur.

En fait, la conversion ascendante et descendante sont toutes deux autorisées en C++. Mais lors de l'utilisation du downcasting, 2 choses doivent être prises en compte: 1 La superclasse doit avoir au moins une méthode virtuelle. 2 Étant donné que la superclasse est "plus petite" que la sous-classe, il convient d'utiliser soigneusement l'objet mémoire.

2
tyger