本文介绍如何在运行时访问有关对象的类的信息。
注释
MFC 不使用在 Visual C++ 4.0 中引入的 Run-Time 类型信息(RTTI)支持。
如果从 CObject 派生出类,并使用文章 从 CObject 派生类 中解释的 DECLARE_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
,并使用DECLARE_DYNAMIC宏,以及文章IMPLEMENT_DYNAMIC
中介绍的DECLARE_DYNCREATE
和IMPLEMENT_DYNCREATE
、DECLARE_SERIAL
和IMPLEMENT_SERIAL
或宏。对于该类的对象,调用成员函数,并使用
IsKindOf
宏生成RUNTIME_CLASS
参数,如下所示: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 中的文件和序列化的文章。