Why is DECLARE_DYNAMIC & IMPLEMENT_DYNAMIC nessary for DYNAMIC_DOWNCAST?

强颜欢笑 提交于 2019-11-29 17:06:56

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).

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!