c++ - уроки - mfc что это




Классы MFC и стили в стиле C++ (2)

Мне интересно, если я не полностью понял C ++ casts против старого C-Style. В MFC у меня есть этот метод:

Вероятно, вы хорошо понимаете разницу, но MFC был выпущен до RTTI в стандарте C ++, имея собственную поддержку RTTI , которая не соответствует стандартным образом .

Таким образом, вместо этого вы можете использовать DYNAMIC_DOWNCAST следующим образом:

DYNAMIC_DOWNCAST(CEdit, GetDlgItem(IDC_EDIT1));

Однако обычной практикой для этого является не создание, а создание переменной-члена, которая представляет ваш элемент управления MFC, используя DDX_Control , который вы можете легко выполнить, выполнив правый щелчок и выбрав « Добавить переменную ...» или через MFC Class Wizzard ,

EDIT Итак, я неправильно понял важную часть вопроса о том, когда происходит авария. nullptr произошел из-за разыменования nullptr , действительного результата dynamic_cast , а не самого dynamic_cast . @xMRi отвечает, почему он падает в деталях.

Мне интересно, если я не полностью понял C ++ casts против старого C-Style. В MFC у меня есть этот метод:

CWnd * GetDlgItem(UINT uResId);

Я ожидаю, что CComboBox (или CEdit), который получен из CWnd, требует такого рода трансляции:

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 .

Если вы хотите проверить, действительно ли это окно является CWnd::GetClassName управления Edit вы можете использовать CWnd::GetClassName . Кастинг в CEdit* безопасен и удобен, потому что контроллер CEdit взаимодействует с его HWND копией только через сообщения Window. Таким образом, это работает для всех основных интегрированных оконных классов.





mfc