Différence de comportement tout en utilisant dynamic_cast en référence et pointeurs
-
16-09-2019 - |
Question
Je vérifiais le comportement des dynamic_cast et a constaté que quand il échoue, std :: exception bad_cast est lancée que si la destination est un type de référence. Si la destination est un type de pointeur alors aucune exception est levée de la distribution. Ceci est mon exemple de code:
class A
{
public:
virtual ~A()
{
}
};
class B : public A
{
};
int main()
{
A* p = new A;
//Using reference
try
{
B& b = dynamic_cast<B&>(*p);
}
catch(std::bad_cast exp)
{
std::cout<<"Caught bad cast\n";
}
//Using pointer
try
{
B* pB = dynamic_cast<B*>(p);
if( pB == NULL)
{
std::cout<<"NULL Pointer\n";
}
}
catch(std::bad_cast exp)
{
std::cout<<"Caught bad cast\n";
}
return 0;
}
La sortie est "cast Caught mauvais" et "pointeur NULL". Le code est compilé en utilisant VS2008. Est-ce le bon comportement? Si oui, alors pourquoi il y a une différence?
La solution
Oui, ce comportement est correct. La raison est que vous pouvez avoir un pointeur NULL, mais pas une référence null -. Toute référence doit être lié à un objet
Alors, quand dynamic_cast pour un type de pointeur échoue, il renvoie un pointeur NULL et l'appelant peut vérifier, mais quand il échoue pour un type de référence ne peut pas renvoyer une référence nulle, donc une exception est la seule façon raisonnable de signaler un problème.
Autres conseils
Voir la norme C ++, section 5.2.7 / 9:
9 La valeur d'une distribution pas le type de pointeur est la valeur de pointeur null du type de résultat requis. Un échec coulée du type référence jette bad_cast (18.5.2).
Quant à savoir pourquoi - ce sont les mots du livre D & E Stroustrup, section 14.2.2:
J'utilise un casting de référence quand je veux un hypothèse sur un type de référence vérifié et considérer comme un échec pour mon hypothèse erronée. Si, au lieu Je veux choisir parmi plausible alternatives, j'utilise un casting de pointeur et tester le résultat.
Oui, 5.2.7 / 9
La valeur d'une distribution pas le type de pointeur est la valeur de pointeur null du type de résultat souhaité. A a échoué jeté à la référence de type lance bad_cast (18.5.2).
Oui, il est. Parce que dynamic_cast
ne peut pas retourner NULL pour une coulée de référence a échoué, une exception est la seule façon.
C'est une référence ne peut pas être NULL, donc il n'y a rien de convenable pour revenir.