zoukankan      html  css  js  c++  java
  • 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);
       

    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<Derived*>(pB);

    常记溪亭日暮,沉醉不知归路。兴尽晚回舟,误入藕花深处。争渡,争渡,惊起一滩鸥鹭。

    昨夜雨疏风骤,浓睡不消残酒。试问卷帘人,却道海棠依旧。知否?知否?应是绿肥红瘦。
  • 相关阅读:
    idea安装
    IntelliJ IDEA 简单使用
    git客户端安装
    一、AJAX
    一、JSP标签介绍,自定义标签
    注解
    线程
    网络编程Socket
    一 批量插入数据(使用批处理
    day87
  • 原文地址:https://www.cnblogs.com/htj10/p/13053802.html
Copyright © 2011-2022 走看看