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)))
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);
常记溪亭日暮,沉醉不知归路。兴尽晚回舟,误入藕花深处。争渡,争渡,惊起一滩鸥鹭。
昨夜雨疏风骤,浓睡不消残酒。试问卷帘人,却道海棠依旧。知否?知否?应是绿肥红瘦。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义