这是 MFC 中的内存泄漏吗

2022-01-12 00:00:00 memory-leaks c++ mfc
// CMyDialog inherits from CDialog 
void CMyFrame::OnBnClickedCreate()
{
    CMyDialog* dlg = new CMyDialog();
    dlg->Create( IDD_MYDIALOG, m_thisFrame );
    dlg->ShowWindow( SW_SHOW );
}

我很确定这会泄漏.我真正要问的是:MFC 中是否有任何魔法"可以在对话框被销毁时进行对话框清理.如果 dlg 不是指针而是在堆栈上声明,它将如何工作 - 当 dlg 超出范围时,析构函数不会破坏窗口.

I'm pretty sure this leaks. What I'm really asking is: is there any "magic" in MFC that does dialog cleanup when the dialog is destroyed. How would it work if dlg wasn't a pointer but declared on the stack - wouldn't the destructor destroy the window when dlg goes out of scope.

推荐答案

是的,在你的情况下是内存泄漏,但你可以通过使用重写 PostNcDestroy 在堆上分配无模式对话框的情况下避免内存泄漏.

Yes, it is memory leak in your case but you can avoid memory leak in cases where modeless dialog allocated on the heap by making use of overriding PostNcDestroy.

对话框不是为自动清理而设计的(主框架窗口和视图窗口都是).如果你想为对话框提供自动清理,那么你必须在你的派生类中重写 PostNcDestroy 成员函数.要为您的类添加自动清理,请调用您的基类,然后执行 delete this.要从您的类中删除自动清理,请直接调用 CWnd::PostNcDestroy 而不是直接基类中的 PostNcDestroy 成员.

Dialogs are not designed for auto-cleanup ( where as Main frame windows, View windows are). In case you want to provide the auto-cleanup for dialogs then you must override the PostNcDestroy member function in your derived class. To add auto-cleanup to your class, call your base class and then do a delete this. To remove auto-cleanup from your class, call CWnd::PostNcDestroy directly instead of the PostNcDestroy member in your direct base class.

void MyDialog::PostNcDestroy() 
{

    CDialog::PostNcDestroy();
    delete this;
}

这是如何工作的(来自 MSDN):

How this works (from MSDN):

销毁 Windows 窗口时,最后一条 Windows 消息发送到窗口是 WM_NCDESTROY.默认该消息的 CWnd 处理程序(CWnd::OnNcDestroy) 将分离来自 C++ 对象的 HWND 并调用虚函数 PostNcDestroy.一些类将这个函数重写为删除 C++ 对象.

When destroying a Windows window, the last Windows message sent to the window is WM_NCDESTROY. The default CWnd handler for that message (CWnd::OnNcDestroy) will detach the HWND from the C++ object and call the virtual function PostNcDestroy. Some classes override this function to delete the C++ object.

"delete this" 将释放任何 C++与 C++ 对象关联的内存.即使默认的 CWnd析构函数调用 DestroyWindow 如果m_hWnd 是非 NULL,这不会导致自句柄以来无限递归期间将被分离并为 NULL清理阶段.

"delete this" will free any C++ memory associated with the C++ object. Even though the default CWnd destructor calls DestroyWindow if m_hWnd is non-NULL, this does not lead to infinite recursion since the handle will be detached and NULL during the cleanup phase.

您也可以参考 MSDN (销毁窗口对象 )更多细节.

You can also refer MSDN (Destroying Window Objects ) for further details.

注意:

这适用于可以在堆上分配的无模式对话框.

This works for modeless dialog that can be allocated on the heap.

相关文章