DYNAMIC_DOWNCAST is a throw back to how you used to have to do dynamic casting before RTTI information was available from the compiler. The casting information is created using the macros DECLARE_DYNAMIC and IMPLEMENT_DYNAMIC which use the class CRuntimeClass to decide if the cast is valid.
DYNAMIC_DOWNCAST simply does this:
CObject* AFX_CDECL AfxDynamicDownCast(CRuntimeClass* pClass, CObject* pObject)
{
if (pObject != NULL && pObject->IsKindOf(pClass))
return pObject;
else
return NULL;
}
The DECLARE_DYNAMIC macro adds this code:
#define DECLARE_DYNAMIC(class_name)
protected:
static CRuntimeClass* PASCAL _GetBaseClass();
public:
static const CRuntimeClass class##class_name;
static CRuntimeClass* PASCAL GetThisClass();
virtual CRuntimeClass* GetRuntimeClass() const;
Add IMPLEMENT_DYNAMIC adds this code:
#define IMPLEMENT_RUNTIMECLASS(class_name, base_class_name, wSchema, pfnNew, class_init)
CRuntimeClass* PASCAL class_name::_GetBaseClass()
{ return RUNTIME_CLASS(base_class_name); }
AFX_COMDAT const CRuntimeClass class_name::class##class_name = {
#class_name, sizeof(class class_name), wSchema, pfnNew,
&class_name::_GetBaseClass, NULL, class_init };
CRuntimeClass* PASCAL class_name::GetThisClass()
{ return _RUNTIME_CLASS(class_name); }
CRuntimeClass* class_name::GetRuntimeClass() const
{ return _RUNTIME_CLASS(class_name); }
#define IMPLEMENT_DYNAMIC(class_name, base_class_name)
IMPLEMENT_RUNTIMECLASS(class_name, base_class_name, 0xFFFF, NULL, NULL)
I imagine few people still use this for new projects, instead preferring the C++ standard dynamic_cast<>
call (along with static_cast
and reinterpret_cast
).
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…