2017-04-09 6 views
1

Je me demande encore pourquoi ce qui suit donne std::bad_cast exceptionexception bad_cast lancé lorsque vous faites downcasting de l'objet de la classe de base par référence à l'objet de classe dérivée

#include <typeinfo> 
class A {virtual void fun() {}}; 
class B : public A {}; 
int main() { 
    try { 
     A a; 
     B b = dynamic_cast<B&>(a); 
    } catch (std::bad_cast& e) { 
     std::cerr << e.what() << '\n'; 
    } 
} 

classe A est une classe polymorphique classe B est publiquement dérivé de A correctement faire un downcast de la classe de base A objet par référence, dynamic_cast accepte un argument de référence mais encore pourquoi cette exception?

+2

Vous attendiez-vous à ce que l'opérateur de distribution retourne une référence à un objet B valide? Où pourrait-il en trouver un? –

+1

'A a' n'est pas un' B', donc l'échec de cast est le bon comportement. – dasblinkenlight

+1

Si vous ne voulez pas d'exception, placez-le sur un pointeur au lieu d'une référence, puis vérifiez la valeur de retour par rapport à nullptr pour voir si la distribution a réussi. – xaxxon

Répondre

3

C'est ce que doit faire dynamic_cast. a est un objet de A en fait, la conversion à la classe dérivée B échouerait. D'un autre côté, si vous convertissez quelque chose avec un type de référence ou un pointeur vers la classe de base, mais fait référence à un objet de B en fait, alors cela fonctionnera bien. par exemple.

B b1; 
A& ra = b1; 
B b2 = dynamic_cast<B&>(ra); 
2

Ce que vous avez essentiellement dit est "J'ai un animal, mais est-ce un lion?"

Et la langue doit être capable de dire "oui c'est un lion" ou "non ce n'est pas un lion".

Quand vous lancez un type de pointeur, il peut dire « non » en retournant nullptr pour vous ou le pointeur réelle à un lion si « oui »

Cependant, il n'y a pas une telle chose comme une référence nulle. Pour cette raison, lorsque vous lancez une référence, il faut un mécanisme différent pour vous informer que votre animal n'est pas un lion. Il jette une exception de distribution incorrecte dans ce cas.