Modifications avec rupture dans dynamic_cast
Mise à jour : novembre 2007
Dans Microsoft Visual C++ 2005 ainsi que dans Visual C++ .NET 2002, des modifications ont été apportées à l'opérateur dynamic_cast et le comportement de votre application peut donc changer.
Le compilateur de Visual C++ 6.0 permettait une vérification à l'exécution, lorsqu'une vérification au moment de la compilation était requise par la norme. Ce problème a été résolu dans Visual C++ .NET 2002 (Visual C++ 7.0).
La bibliothèque Runtime C effectue désormais une vérification de dynamic_cast à l'exécution pour garantir que le type au moment de la compilation de l'expression sur laquelle un cast est effectué fait référence à un sous-objet de classe de base public du type cible cast (pour un downcast) ou du type d'objet le plus dérivé (pour un cross-cast).
Pour plus d'informations sur les modifications du compilateur, consultez Modifications avec rupture dans le compilateur Visual C++.
Exemple
Description
Dans cet exemple de code, la variable pA2 a la valeur Null dans VC6 ; le compilateur n'a pas exécuté de vérification d'identité comme spécifié dans la section 5.2.7/3 de la norme ISO C++. Toutefois, le démarrage de ce cast aboutira dans Visual C++ .NET 2002 (Visual C++ 7.0).
Ainsi, tandis que cela provoquait la levée d'une exception dans Visual C++ 6.0, aucune exception n'est désormais levée.
Code
// dynamic_cast_breaking_change.cpp
struct A {
virtual void F() {}
};
struct B {
virtual void F() {}
};
void Test(A* pA) {
A* pA2 = dynamic_cast<A*>(pA);
A& rA = dynamic_cast<A&>(*pA);
}
int main() {
B* pB = new B;
Test(reinterpret_cast<A*>(pB));
}
Exemple
Description
Cet exemple indique que la bibliothèque Runtime C effectue désormais une vérification de dynamic_cast à l'exécution pour garantir que le type au moment de la compilation de l'expression sur laquelle un cast est effectué fait référence à un sous-objet de classe de base public du type cible cast (pour un downcast) ou du type d'objet le plus dérivé (pour un cross-cast).
Dans les versions précédentes de Visual C++, ces casts dynamiques aboutissaient.
Code
// dynamic_cast_breaking_change_2.cpp
#include "stdio.h"
struct A {
virtual void Test() {}
};
struct B : virtual private A {
virtual void Test() {}
};
struct D : virtual private A {
virtual void Test() {}
};
struct C : public B, public D {
virtual void Test() {}
};
int main() {
C c;
printf("%p\n", dynamic_cast<B*>((A*)&c) );
printf("%p\n", dynamic_cast<C*>((A*)&c) );
}
Résultat de l'exemple
00000000
00000000
Exemple
Description
Cet exemple indique que si n'importe quel sous-objet de la source à la cible du cast n'est pas public, le cast dynamic_cast échouera.
Code
// dynamic_cast_breaking_change_3.cpp
#include "stdio.h"
struct A {
virtual void Test() {}
};
struct B : virtual public A {
virtual void Test() {}
};
struct C : virtual private B {
virtual void Test() {}
};
int main() {
C c;
printf("%p\n", dynamic_cast<B*>((A*)&c) );
printf("%p\n", dynamic_cast<C*>((A*)&c) );
}
Résultat de l'exemple
0012FF70
00000000