访问运行时类信息
本文说明了如何在运行时访问对象的类的相关信息。
注意
MFC 不使用 Visual C++ 4.0 中引入的运行时类型信息 (RTTI) 支持。
如果已从 CObject 派生类并使用了从 CObject 派生类一文中介绍的 DECLARE_DYNAMIC 和 IMPLEMENT_DYNAMIC
、DECLARE_DYNCREATE
和 IMPLEMENT_DYNCREATE
、或 DECLARE_SERIAL
和 IMPLEMENT_SERIAL
宏,则 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; }
注意
如果对象是指定类的成员或派生自指定类的类的成员,则 IsKindOf 将返回 TRUE。
IsKindOf
不支持多重继承或虚拟基类,但您可以根据需要对派生的 Microsoft 基础类使用多重继承。
运行时类信息的一种用法是在对象的动态创建中。 动态对象创建一文中讨论了这一过程。
有关序列化和运行时类信息的更多详细信息,请参阅文章 MFC 中的文件和序列化。