首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么DECLARE_DYNAMIC & IMPLEMENT_DYNAMIC对于DYNAMIC_DOWNCAST来说是必不可少的?

为什么DECLARE_DYNAMIC & IMPLEMENT_DYNAMIC对于DYNAMIC_DOWNCAST来说是必不可少的?
EN

Stack Overflow用户
提问于 2013-01-14 21:07:58
回答 1查看 6.5K关注 0票数 2

我有两个类:

代码语言:javascript
复制
/*Switch.h*/
    class CSwitch : public CDeviceEntity {}
/*EndSystem.h*/
    class CEndSystem : public CDeviceEntity {}

但是当我使用的时候:

代码语言:javascript
复制
CDeviceEntity* dev = NULL;
dev = topo->headList[i]->node;
if ( DYNAMIC_DOWNCAST( CEndSystem, dev ) != NULL ) {}

"DYNAMIC_DOWNCAST“总是返回not NULL,而dev是一种class CEndSystemclass CSwitch

如果使用:

代码语言:javascript
复制
/*Switch.h*/
    class CSwitch : public CDeviceEntity { DECLARE_DYNAMIC(CSwitch) } 
    and
/*Switch.cpp*/
    IMPLEMENT_DYNAMIC(CSwitch, CDeviceEntity)
/*EndSystem.h*/
    class CEndSystem : public CDeviceEntity { DECLARE_DYNAMIC(CEndSystem) }
    and
/*EndSystem.cpp*/
    IMPLEMENT_DYNAMIC(CEndSystem, CDeviceEntity)

"DYNAMIC_DOWNCAST“根据class CEndSystemclass CSwitch返回NULLnot NULL

为什么"DECLARE_DYNAMIC“和"IMPLEMENT_DYNAMIC”是"DYNAMIC_DOWNCAST“的必需品?

代码语言:javascript
复制
/*Algorithm.h*/
static int getESNum();

/*Algorithm.cpp*/
int CAlgorithm::getESNum()
{
    int count = 0;
    CDeviceEntity* dev = NULL;
    for (int i = 0; i < topo->nodeNum; i++)
    {
        dev = topo->headList[i]->node;
        if ( DYNAMIC_DOWNCAST( CEndSystem, dev ) != NULL )
        {
            count++;
        }
    }

    return count;
}

/*Algorithm.h*/
static int getSWNum();

/*Algorithm.cpp*/
int CAlgorithm::getSWNum()
{
    int count = 0;
    CDeviceEntity* dev = NULL;
    for (int i = 0; i < topo->nodeNum; i++)
    {
        dev = topo->headList[i]->node;
        if ( DYNAMIC_DOWNCAST(CSwitch, dev) != NULL )
        {
            count++;
        }
    }

    return count;
}

并在保存文档时以序列化方式调用这些函数。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-01-14 21:48:17

在编译器提供RTTI信息之前,DYNAMIC_DOWNCAST是对过去必须进行动态强制转换的一种回归。转换信息是使用宏DECLARE_DYNAMIC和IMPLEMENT_DYNAMIC创建的,这两个宏使用类CRuntimeClass来确定转换是否有效。

DYNAMIC_DOWNCAST只需执行以下操作:

代码语言:javascript
复制
CObject* AFX_CDECL AfxDynamicDownCast(CRuntimeClass* pClass, CObject* pObject)
{
    if (pObject != NULL && pObject->IsKindOf(pClass))
        return pObject;
    else
        return NULL;
}

DECLARE_DYNAMIC宏会添加以下代码:

代码语言:javascript
复制
#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添加以下代码:

代码语言:javascript
复制
#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)

我想很少有人还会在新项目中使用它,而是更喜欢C++标准的dynamic_cast<>调用(以及static_castreinterpret_cast)。

票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/14318993

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档