Accessing Run-Time Class Information
The latest version of this topic can be found at Accessing Run-Time Class Information.
This article explains how to access information about the class of an object at run time.
Note
MFC does not use the Run-Time Type Information (RTTI) support introduced in Visual C++ 4.0.
If you have derived your class from CObject and used the DECLARE_DYNAMIC and IMPLEMENT_DYNAMIC
, the DECLARE_DYNCREATE
and IMPLEMENT_DYNCREATE
, or the DECLARE_SERIAL
and IMPLEMENT_SERIAL
macros explained in the article Deriving a Class from CObject, the CObject
class has the ability to determine the exact class of an object at run time.
This ability is most useful when extra type checking of function arguments is needed and when you must write special-purpose code based on the class of an object. However, this practice is not usually recommended because it duplicates the functionality of virtual functions.
The CObject
member function IsKindOf
can be used to determine if a particular object belongs to a specified class or if it is derived from a specific class. The argument to IsKindOf
is a CRuntimeClass
object, which you can get using the RUNTIME_CLASS
macro with the name of the class.
To use the RUNTIME_CLASS macro
Use
RUNTIME_CLASS
with the name of the class, as shown here for the classCObject
:CRuntimeClass* pClass = RUNTIME_CLASS( CObject );
You will rarely need to access the run-time class object directly. A more common use is to pass the run-time class object to the IsKindOf
function, as shown in the next procedure. The IsKindOf
function tests an object to see if it belongs to a particular class.
To use the IsKindOf function
Make sure the class has run-time class support. That is, the class must have been derived directly or indirectly from
CObject
and used the DECLARE_DYNAMIC andIMPLEMENT_DYNAMIC
, theDECLARE_DYNCREATE
andIMPLEMENT_DYNCREATE
, or theDECLARE_SERIAL
andIMPLEMENT_SERIAL
macros explained in the article Deriving a Class from CObject.Call the
IsKindOf
member function for objects of that class, using theRUNTIME_CLASS
macro to generate theCRuntimeClass
argument, as shown here: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 returns TRUE if the object is a member of the specified class or of a class derived from the specified class.
IsKindOf
does not support multiple inheritance or virtual base classes, although you can use multiple inheritance for your derived Microsoft Foundation classes if necessary.
One use of run-time class information is in the dynamic creation of objects. This process is discussed in the article Dynamic Object Creation.
For more detailed information on serialization and run-time class information, see the articles Files in MFC and Serialization.