ランタイム クラス情報へのアクセス方法

この記事では、オブジェクトのクラスに関する情報に、実行時にアクセスする方法を説明します。

Note

Visual C++ 4.0 で導入された実行時型情報 (RTTI: Run-Time Type Information) のサポートは、MFC では使用されません。

CObject からクラスを派生させ、DECLARE_DYNAMICIMPLEMENT_DYNAMICDECLARE_DYNCREATEIMPLEMENT_DYNCREATE、または DECLARE_SERIALIMPLEMENT_SERIAL マクロ (「CObject からのクラスの派生」の記事を参照) を使用した場合、その CObject クラスには、任意のオブジェクトの正確なクラスを実行時に特定する機能が備わっています。

関数の引数に対する型チェックが別途必要な場合や、オブジェクトのクラスに基づいて特殊用途のコードを記述しなければならない場合、この機能は非常に役立ちます。 ただし、この手法は仮想関数の機能と重複するため、通常は推奨されません。

CObject のメンバー関数 IsKindOf を使用すると、特定のオブジェクトが特定のクラスに属しているかどうかや特定のクラスから派生されたものであるかどうかを判別できます。 IsKindOf に対する引数は CRuntimeClass オブジェクトで、これは RUNTIME_CLASS マクロとクラスの名前を使用して取得できます。

RUNTIME_CLASS マクロを使用するには

  1. RUNTIME_CLASS にクラスの名前を指定します。以下に示したのは、CObject クラスを使用した例です。

    CRuntimeClass *pClass = RUNTIME_CLASS(CObject);
    

ランタイム クラス オブジェクトに直接アクセスしなければならない状況というのはまれです。 より一般的なのは、この後の手順で示したように、ランタイム クラス オブジェクトを IsKindOf 関数に渡すという使い方です。 IsKindOf は、オブジェクトが特定のクラスに属しているかどうかを判定する関数です。

IsKindOf 関数を使用するには

  1. ランタイム クラスをサポートするクラスであることを確認します。 つまり、CObject から直接または間接的に派生したクラスで、なおかつ「CObject からのクラスの派生」の記事で説明されている DECLARE_DYNAMICIMPLEMENT_DYNAMICDECLARE_DYNCREATEIMPLEMENT_DYNCREATE、または DECLARE_SERIALIMPLEMENT_SERIAL マクロが使用されている必要があります。

  2. そのクラスのオブジェクトの 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 のファイル」およびシリアル化に関する記事を参照してください。

関連項目

CObject の使い方