dynamic_cast の互換性に影響する変更点

更新 : 2007 年 11 月

Microsoft Visual C++ 2005 では、Visual C++ .NET 2002 と同様、dynamic_cast 演算子について変更がありました。そのため、アプリケーションの動作が異なる場合があります。

  • 標準でコンパイル時チェックが必要とされているときに、Visual C++ 6.0 コンパイラは、ランタイム チェックの実行を許可していました。Visual C++ .NET 2002 (Visual C++ 7.0) で、これは解決されました。

  • 現在、C ランタイム ライブラリは、dynamic_cast ランタイム チェックを行って、キャストである式のコンパイル時の型が、キャスト対象の型 (ダウンキャストの場合) または最派生オブジェクトの型 (クロスキャストの場合) のどちらかのパブリック基本クラス サブ オブジェクトを参照していることを確認するようになりました。

コンパイラに対する変更点の詳細については、「Visual C++ コンパイラの互換性に影響する変更点」を参照してください。

説明

このコード例において、VC6 では、変数 pA2 は NULL です。コンパイラは、ISO C++ 標準の 5.2.7/3 で指定されている ID チェックを行いませんでした。しかし、このキャストは、Visual C++ .NET 2002 (Visual C++ 7.0) では実行されます。

そのため、Visual C++ 6.0 では例外がスローされましたが、今後は例外がスローされることはありません。

コード

// 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));
}

説明

このコード例に示されているように、C ランタイム ライブラリは、dynamic_cast ランタイム チェックを行って、キャストである式のコンパイル時の型が、キャスト対象の型 (ダウンキャストの場合) または最派生オブジェクトの型 (クロスキャストの場合) のどちらかのパブリック基本クラス サブ オブジェクトを参照していることを確認します。

以前の Visual C++ リリースでは、これらのダイナミック キャストは成功していました。

コード

// 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) );
}

出力例

00000000
00000000

説明

このコード例では、キャストのソースからターゲットへのサブ オブジェクトにパブリックでないサブ オブジェクトがあった場合、dynamic_cast キャストは失敗します。

コード

// 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) );
}

出力例

0012FF70
00000000

参照

参照

dynamic_cast Operator