2

私には2つのクラスがあります:

/*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 ) {}

" " devがorのようなものである間、DYNAMIC_DOWNCAST常に戻ります。not NULLclass 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返します。NULLnot NULLclass CEndSystemclass CSwitch

なぜ「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;
}

また、ドキュメントを保存するときに、シリアル化で関数が呼び出されます。

4

1 に答える 1

6

DYNAMIC_DOWNCASTは、RTTI情報がコンパイラーから利用可能になる前に動的キャストを実行しなければならなかった方法への逆戻りです。キャスト情報は、クラスCRuntimeClassを使用してキャストが有効かどうかを判断するマクロDECLARE_DYNAMICおよびIMPLEMENT_DYNAMICを使用して作成されます。

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

Add 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

于 2013-01-14T13:48:17.310 に答える