我想知道我是否还没有完全理解C++强制转换和旧的C-Style强制转换。在MFC中,我有以下方法:
CWnd * GetDlgItem(UINT uResId);
我期望CComboBox(或CEdit)(来自CWnd的derived)需要这种类型的转换:
dynamic_cast<CComboBox *>(GetDlgItem(IDC_COMBO1));
// for CEdit:
dynamic_cast<CEdit *>(GetDlgItem(IDC_EDIT1));
但是此操作会导致使用空指针的崩溃,这意味着强制转换已失败。使用:
reinterpret_cast<CComboBox *>(GetDlgItem(IDC_COMBO1));
// for CEdit:
reinterpret_cast<CEdit *>(GetDlgItem(IDC_EDIT1));
解决了问题,但我很失望。
我想念什么?
最佳答案
问题在于GetDlgItem
可能会返回一个临时的CWnd*
指针。
如果该窗口是CWnd
派生的类,并且该窗口是使用CWnd::Create(Ex)
创建的,或者该窗口是子类的,则RTTI将起作用。
当窗口是由Windows创建的(由于对话框模板)而窗口不是由MFC子类化(带有DDX_Control
ow CWnd::SubclassWindow
)时,GetDlgItem
仅返回带有CWnd*
的临时CWnd::FromHandle
。该窗口句柄始终是CWnd
的基本类型。
如果要检查此窗口是否确实是Edit
控件,则可以使用CWnd::GetClassName
。强制转换为CEdit*
既安全又方便,因为CEdit
控件仅通过Window消息与其对应的HWND
进行通信。因此,这适用于所有基本的集成窗口类。