// CMyDialog inherits from CDialog
void CMyFrame::OnBnClickedCreate()
{
CMyDialog* dlg = new CMyDialog();
dlg->Create( IDD_MYDIALOG, m_thisFrame );
dlg->ShowWindow( SW_SHOW );
}
我很确定这个漏洞。我真正要问的是:当对话框被销毁时,MFC中是否存在对话清理的“魔力”。如果dlg不是指针而是在堆栈中声明,它将如何工作 - 当dlg超出范围时,析构函数不会破坏窗口。
答案 0 :(得分:16)
是的,在您的情况下是内存泄漏,但是如果通过使用覆盖PostNcDestroy
在堆上分配无模式对话框,则可以避免内存泄漏。
对话框不是为自动清理而设计的(主框架窗口,视图窗口都是这样)。
如果要为对话框提供自动清理,则必须覆盖派生类中的PostNcDestroy
成员函数。要在类中添加自动清理,请调用基类,然后执行delete this
。要从班级中删除自动清理,请直接致电CWnd::PostNcDestroy
,而不是直接基类中的PostNcDestroy
成员。
void MyDialog::PostNcDestroy()
{
CDialog::PostNcDestroy();
delete this;
}
这是如何工作的(来自MSDN):
当破坏Windows窗口时, 最后发送给Windows的Windows消息 窗口是WM_NCDESTROY。默认 该消息的CWnd处理程序 (CWnd :: OnNcDestroy)将分离 来自C ++对象的HWND并调用 虚函数PostNcDestroy。一些 类重写此函数 删除C ++对象。
“删除此”将释放任何C ++ 与C ++对象关联的内存。 即使是默认的CWnd 析构函数调用DestroyWindow if m_hWnd是非NULL,这不会导致 自句柄以来无限递归 将被分离并且在期间为NULL 清理阶段。
您还可以参考MSDN(Destroying Window Objects)了解更多详情。
注意:强>
这适用于可以在堆上分配的无模式对话框。
答案 1 :(得分:4)
是的,那是泄密。是的,如果对象是堆栈分配的话,窗口将被销毁。使用对话框作为堆栈分配的对象是模态对话框的典型对象 - 您可以调用一个方法将对话框显示为模式窗口,该方法仅在对话框关闭且对象在此之后被销毁时返回。
答案 2 :(得分:3)
如果您在对话框中手动调用 Create
,则还必须手动 Destroy
。
使用 DoModal()
时,这不是必需的。
来自MSDN:
使用CWnd :: DestroyWindow函数 销毁由...创建的对话框 创建功能。