c++ - 为什么 DECLARE_DYNAMIC 和 IMPLEMENT_DYNAMIC 对 DYNAMIC_DOWNCAST 是必要的?

标签 c++ dynamic mfc downcast

我有两个类:

/*Switch.h*/
    class CSwitch : public CDeviceEntity {}
/*EndSystem.h*/
    class CEndSystem : public CDeviceEntity {}

但是当我使用时:

CDeviceEntity* dev = NULL;
dev = topo->headList[i]->node;
if ( DYNAMIC_DOWNCAST( CEndSystem, dev ) != NULL ) {}

DYNAMIC_DOWNCAST”总是返回 not NULL 而 dev 是 class CEndSystemclass CSwitch

如果使用:

/*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”是必需的?

/*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;
}

并且在保存文档时在序列化中调用这些函数。

最佳答案

DYNAMIC_DOWNCAST 是对您在 RTTI 之前必须进行动态转换的倒退。信息可从编译器获得。转换信息是使用宏 DECLARE_DYNAMIC 和 IMPLEMENT_DYNAMIC 创建的,它们使用类 CRuntimeClass 来决定转换是否有效。

DYNAMIC_DOWNCAST 只是这样做:

CObject* AFX_CDECL AfxDynamicDownCast(CRuntimeClass* pClass, CObject* pObject)
{
    if (pObject != NULL && pObject->IsKindOf(pClass))
        return pObject;
    else
        return NULL;
}

DECLARE_DYNAMIC 宏添加了这段代码:

#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; \

添加 IMPLEMENT_DYNAMIC 添加此代码:

#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 )。

关于c++ - 为什么 DECLARE_DYNAMIC 和 IMPLEMENT_DYNAMIC 对 DYNAMIC_DOWNCAST 是必要的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14318993/

相关文章:

c++ - 将模板转换为任意类型时如何避免编译器错误

c++ - 如何将显式声明的构造函数分离到 .h 和 .cpp 文件中?

java - 是否可以做一个动态 LLVM 汇编器(来自 Java 等高级语言)?

sql-server - "String data, right truncation"select 语句上的警告

c++ - shared_ptr 的基本语法问题

c++ - 如何将 wchar_t* 转换为 std::string?

python - 在 Python 中从文本文件导入数据和变量名称

php - 将可变变量与超全局数组一起使用

visual-studio-2008 - 奇怪的 MFC/VC++ 链接器错误(std::list<CRect> 已定义)

c++ - 从 mfc 对话框应用程序读取和写入 xml 文档