Partager via


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

Voir aussi

Référence

dynamic_cast Operator