DYNAMIC_DOWNCAST 和 dynamic_cast

DYNAMIC_DOWNCAST

DYNAMIC_DOWNCAST 是MFC中的,字面意思是,“动态向下转型”,主要用于 父类指针 转换为 子类指针,安全,可以用返回是否为 NULL 判断;而用强制转换,不安全。

必须是由MFC中的CObject派生,且支持了RTTI(运行时类型识别)即 DECLARE_DYNAMIC / IMPLEMENT_DYNAMIC 看:MFC中动态创建DECLARE_DYNCREATE和运行时类型识别DECLARE_DYNAMIC

例如:

// 这个object参数,就是pointer(指针)

#define DYNAMIC_DOWNCAST(class_name, object)

(class_name)AfxDynamicDownCast(RUNTIME_CLASS(class_name), object)



CObject
AFX_CDECL AfxDynamicDownCast(CRuntimeClass pClass, CObject pObject)

{

if(pObject != NULL && pObject->IsKindOf(pClass))

return pObject;

else

return NULL;

}



//使用方法

class_name p = DYNAMIC_DOWNCAST(class_name, pointer);

//将指针pointer安全地转换为 class_name
,若pointer确是指向class_name类型的对象,则返回适当的指针;否则,返回NULL



//强制类型转换(不安全),因为,若pointer不指向class_name类型的对象,没有提示,后续的操作会异常。

class_name p = (class_name)pointer;



//自己写了个MFC对话框类 CMFCDialogDlg,继承CDialog -> CWnd

CWnd pWnd = new CMFCDialogDlg;

CMFCDialogDlg
pDlg = DYNAMIC_DOWNCAST(CMFCDialogDlg, pWnd);//ok

ASSERT(pDlg);

CDialog pDlg2 = DYNAMIC_DOWNCAST(CDialog, pWnd);//ok

ASSERT(pDlg2);

CView
pV = DYNAMIC_DOWNCAST(CView, pWnd);//NULL

ASSERT(pV);


DYNAMIC_DOWNCAST 和 dynamic_castDYNAMIC_DOWNCAST 和 dynamic_cast

class CObject
{
public:

// Object model (types, destruction, allocation)
    virtual CRuntimeClass* GetRuntimeClass() const;
    virtual ~CObject() = 0;  // virtual destructors are necessary

    // Disable the copy constructor and assignment by default so you will get
    //   compiler errors instead of unexpected behaviour if you pass objects
    //   by value or assign objects.
protected:
    CObject();
private:
    CObject(const CObject& objectSrc);              // no implementation
    void operator=(const CObject& objectSrc);       // no implementation

// Attributes
public:
    BOOL IsSerializable() const;
    BOOL IsKindOf(const CRuntimeClass* pClass) const;

// Overridables
    virtual void Serialize(CArchive& ar);

#if defined(_DEBUG) || defined(_AFXDLL)
    // Diagnostic Support
    virtual void AssertValid() const;
    virtual void Dump(CDumpContext& dc) const;
#endif

// Implementation
public:
    static const CRuntimeClass classCObject;
#ifdef _AFXDLL
    static CRuntimeClass* PASCAL _GetBaseClass();
    static CRuntimeClass* PASCAL GetThisClass();
#endif
};

//...cpp
BOOL IsKindOf(const CRuntimeClass* pClass) const  //常量指针
{
  CRuntimeClass* pClassThis = GetRuntimeClass();//GetRuntimeClass()是虚函数,调用的是实际子类中的函数,返回的是实际的类型
  while(pClassThis!=NULL)
  {
    if(pClassThis==pClass)
      return TRUE;
    pClassThis=pClass->m_pBaseClass;//基类的指针是在IMPLEMENT_DYNAMIC过程中赋值的
  }
  return FALSE;
}
//所以,pObject->IsKindOf(RUNTIME_CLASS(类名));当“类名”是 pObject实际指向的对象的类型,或其父类,返回TRUE;否则返回FALSE

// Helper macros
#define _RUNTIME_CLASS(class_name) ((CRuntimeClass*)(&class_name::class##class_name))
#ifdef _AFXDLL
#define RUNTIME_CLASS(class_name) (class_name::GetThisClass())
#else
#define RUNTIME_CLASS(class_name) _RUNTIME_CLASS(class_name)
#endif
#define ASSERT_KINDOF(class_name, object) 
    ASSERT((object)->IsKindOf(RUNTIME_CLASS(class_name)))

View Code

dynamic_cast

dynamic_cast 是C++标准里的,一般都可以使用,包括向下转型(父->子)、向上转型(子->父)。

可以看看这篇博客:C++强制类型转换:static_cast、dynamic_cast、const_cast、reinterpret_cast

例如:

class Base{};

class Derived :public Base

{

//...

};

Base pB = new Derived;

Derived
pD = dynamic_cast(pB);
原文链接: https://www.cnblogs.com/htj10/p/13053802.html

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/198477

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年2月12日 下午7:52
下一篇 2023年2月12日 下午7:52

相关推荐