Je vérifiais le comportement de dynamic_cast et j'ai constaté que lorsqu'il échoue, STD :: Bad_cast Exception n'est lancé que si la destination est un type de référence. Si la destination est un type de pointeur, aucune exception n'est lancé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 "attrapée de mauvaise fonte" et "pointeur null". Le code est compilé à l'aide de VS2008. Est-ce le comportement correct? Si oui, alors pourquoi il y a une différence?
Voir la norme C++, section 5.2.7/9:
9 La valeur d'un type de décloisement échoué au type pointeur est la valeur du pointeur NULL du type de résultat requis. Un déclenchement échoué au type de référence jette Bad_cast (18.5.2).
Quant pourquoi - ce sont des mots de Stroustrup du livre D & E, section 14.2.2:
J'utilise une mise en forme de référence lorsque je veux une hypothèse sur un type de référence vérifié et considérez-la un échec de mon hypothèse. Si nous voulons plutôt choisir parmi des alternatives plausibles, j'utilise un pointeur coulant et testez le résultat.
Oui, 5.2.7/9
La valeur d'un déclencheur ayant échoué au type pointeur est la valeur du pointeur NULL du type de résultat requis. Un déclenchement échoué au type de référence jette Bad_cast (18.5.2).
Oui c'est le cas. Parce que dynamic_cast
Vous ne pouvez pas renvoyer NULL pour une mise en forme d'échec, une exception est la seule sortie.
C'est-à-dire qu'une référence ne peut pas être nulle, il n'y a donc rien de mieux à revenir.