次の方法で共有


Run-Time クラス情報へのアクセス

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

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

CObject からクラスを派生させ、DECLARE_DYNAMICIMPLEMENT_DYNAMICDECLARE_DYNCREATEIMPLEMENT_DYNCREATE、または DECLARE_SERIALに関する記事で説明されているIMPLEMENT_SERIALマクロとマクロを使用した場合、CObject クラスには、実行時にオブジェクトの正確なクラスを決定する機能があります。

この機能は、関数引数の追加の型チェックが必要な場合や、オブジェクトのクラスに基づいて特別な目的のコードを記述する必要がある場合に最も便利です。 ただし、仮想関数の機能が重複するため、通常、この方法はお勧めしません。

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

RUNTIME_CLASS マクロを使用するには

  1. クラス RUNTIME_CLASSに対して次に示すように、クラスの名前でCObjectを使用します。

    CRuntimeClass *pClass = RUNTIME_CLASS(CObject);
    

ランタイム クラス オブジェクトに直接アクセスする必要はほとんどありません。 より一般的な使用方法は、次の手順に示すように、ランタイム クラス オブジェクトを IsKindOf 関数に渡すことです。 IsKindOf関数は、オブジェクトをテストして、それが特定のクラスに属しているかどうかを確認します。

IsKindOf 関数を使用するには

  1. クラスにランタイム クラスのサポートがあることを確認します。 つまり、クラスはCObjectから直接または間接的に派生し、DECLARE_DYNAMICIMPLEMENT_DYNAMICDECLARE_DYNCREATEIMPLEMENT_DYNCREATE、または DECLARE_SERIALに関する記事で説明されているIMPLEMENT_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;
    }
    

    オブジェクトが指定したクラスのメンバーであるか、指定したクラスから派生したクラスのメンバーである場合、IsKindOf は TRUE を 返します。 IsKindOf では、複数の継承または仮想基底クラスはサポートされませんが、必要に応じて、派生した Microsoft Foundation クラスに複数の継承を使用できます。

ランタイム クラス情報の 1 つの用途は、オブジェクトの動的な作成です。 このプロセスについては、 動的オブジェクトの作成に関する記事で説明します。

シリアル化とランタイム クラス情報の詳細については、MFC およびシリアルのファイルに関する記事を参照してください。

こちらも参照ください

CObject の使用