ランタイム クラス情報へのアクセス方法
この記事では、オブジェクトのクラスに関する情報に、実行時にアクセスする方法を説明します。
Note
Visual C++ 4.0 で導入された実行時型情報 (RTTI: Run-Time Type Information) のサポートは、MFC では使用されません。
CObject からクラスを派生させ、DECLARE_DYNAMIC と IMPLEMENT_DYNAMIC
、DECLARE_DYNCREATE
と IMPLEMENT_DYNCREATE
、または DECLARE_SERIAL
と IMPLEMENT_SERIAL
マクロ (「CObject からのクラスの派生」の記事を参照) を使用した場合、その CObject
クラスには、任意のオブジェクトの正確なクラスを実行時に特定する機能が備わっています。
関数の引数に対する型チェックが別途必要な場合や、オブジェクトのクラスに基づいて特殊用途のコードを記述しなければならない場合、この機能は非常に役立ちます。 ただし、この手法は仮想関数の機能と重複するため、通常は推奨されません。
CObject
のメンバー関数 IsKindOf
を使用すると、特定のオブジェクトが特定のクラスに属しているかどうかや特定のクラスから派生されたものであるかどうかを判別できます。 IsKindOf
に対する引数は CRuntimeClass
オブジェクトで、これは RUNTIME_CLASS
マクロとクラスの名前を使用して取得できます。
RUNTIME_CLASS マクロを使用するには
RUNTIME_CLASS
にクラスの名前を指定します。以下に示したのは、CObject
クラスを使用した例です。CRuntimeClass *pClass = RUNTIME_CLASS(CObject);
ランタイム クラス オブジェクトに直接アクセスしなければならない状況というのはまれです。 より一般的なのは、この後の手順で示したように、ランタイム クラス オブジェクトを IsKindOf
関数に渡すという使い方です。 IsKindOf
は、オブジェクトが特定のクラスに属しているかどうかを判定する関数です。
IsKindOf 関数を使用するには
ランタイム クラスをサポートするクラスであることを確認します。 つまり、
CObject
から直接または間接的に派生したクラスで、なおかつ「CObject からのクラスの派生」の記事で説明されている DECLARE_DYNAMIC とIMPLEMENT_DYNAMIC
、DECLARE_DYNCREATE
とIMPLEMENT_DYNCREATE
、またはDECLARE_SERIAL
とIMPLEMENT_SERIAL
マクロが使用されている必要があります。そのクラスのオブジェクトの
IsKindOf
メンバー関数を、RUNTIME_CLASS
マクロを使用して呼び出し、CRuntimeClass
の引数を生成します。その例を次に示します。class CPerson : public CObject { DECLARE_DYNAMIC(CPerson) // other declarations };
IMPLEMENT_DYNAMIC(CPerson, CObject) IMPLEMENT_DYNCREATE(CMyDynCreateObj, CObject) void MemoryCorruptingSnippet(bool bCorrupt) { if (bCorrupt) { CAge *pcage = new CAge(21); // CAge is derived from CObject. Age *page = new Age(22); // Age is NOT derived from CObject. *(((char *)pcage) - 1) = 99; // Corrupt preceding guard byte *(((char *)page) - 1) = 99; // Corrupt preceding guard byte AfxCheckMemory(); } } void SomeFunction(void) { CObject *pMyObject = new CPerson; if (NULL != pMyObject && pMyObject->IsKindOf(RUNTIME_CLASS(CPerson))) { //if IsKindOf is true, then cast is all right CPerson *pmyPerson = (CPerson *)pMyObject; pmyPerson->AssertValid(); // other code goes here... } delete pMyObject; }
Note
IsKindOf はオブジェクトが、指定されたクラスのメンバーであるか、または指定されたクラスから派生したクラスのメンバーである場合に TRUE を返します。 派生した Microsoft Foundation クラスには必要に応じて多重継承を使用できますが、
IsKindOf
は多重継承や仮想基底クラスをサポートしません。
ランタイム クラス情報の用途の 1 つとして、オブジェクトの動的作成があります。 その手順については、「オブジェクトの動的生成」の記事で説明されています。
シリアル化とランタイム クラス情報の詳細については、「MFC のファイル」およびシリアル化に関する記事を参照してください。