2009-06-03 14 views
7
// CMyDialog inherits from CDialog 
void CMyFrame::OnBnClickedCreate() 
{ 
    CMyDialog* dlg = new CMyDialog(); 
    dlg->Create(IDD_MYDIALOG, m_thisFrame); 
    dlg->ShowWindow(SW_SHOW); 
} 

Estoy bastante seguro de que esto tiene fugas. Lo que realmente estoy preguntando es si hay alguna "magia" en MFC que haga la limpieza del diálogo cuando se destruya el diálogo. ¿Cómo funcionaría si dlg no fuera un puntero sino declarado en la pila? ¿No destruiría el destructor la ventana cuando dlg se sale del alcance?Se trata de una pérdida de memoria en MFC

Respuesta

12

sí, es pérdida de memoria en su caso, pero se puede evitar la pérdida de memoria en los casos en que no modal de diálogo asigna en el montón, haciendo uso de anular PostNcDestroy.

Los cuadros de diálogo no están diseñados para la auto-limpieza (donde, como ventanas de marco principal, ventanas de vista). En caso de que desee proporcionar la limpieza automática para los cuadros de diálogo, debe anular la función de miembro PostNcDestroy en su clase derivada. Para agregar la auto-limpieza a su clase, llame a su clase base y luego haga un delete this. Para eliminar la auto-limpieza de su clase, llame directamente al CWnd::PostNcDestroy en lugar del miembro PostNcDestroy en su clase base directa.

void MyDialog::PostNcDestroy() 
{ 

    CDialog::PostNcDestroy(); 
    delete this; 
} 

¿Cómo funciona esto (de MSDN):

Cuando la destrucción de una ventana de Windows, el último mensaje enviado de Windows a la ventana es WM_NCDESTROY. El controlador predeterminado CWnd para ese mensaje (CWnd :: OnNcDestroy) se desconectará el HWND del objeto C++ y llama a la función virtual PostNcDestroy. Algunas clases anulan esta función a eliminan el objeto C++.

"eliminar esto" liberará cualquier C++ memoria asociada con el objeto C++. A pesar de que los predeterminado CWnd llamadas destructor DestroyWindow si m_hWnd no es NULL, esto no conduce a recursividad infinita ya que el mango será separada y NULL durante la fase de limpieza.

También puede consultar MSDN (Destroying Window Objects) para obtener más información.

Nota:

Esto funciona para diálogo no modal que puede ser asignada en el montón .

3

Sí, eso es una pérdida. Y sí, la ventana se destruiría si el objeto se asignara en pila. El uso de cuadros de diálogo como objetos asignados a la pila es típico para los cuadros de diálogo modales: usted llama a un método para mostrar un diálogo como una ventana modal y ese método solo regresa cuando el cuadro de diálogo se cierra y el objeto se destruye después de eso.

+0

Gracias. Olvidé decir que esto es para un diálogo sin modo. Supongo que en este caso para la limpieza, el objeto de diálogo tiene que ser una variable miembro, por lo que se puede destruir/desasignar en el destructor de marcos. – Richard

2

Si llama manualmente Create en un diálogo, usted tiene que manualmente Destroy él también.
Al usar DoModal() esto no es necesario.

De MSDN:

Use la función CWnd :: DestroyWindow para destruir un cuadro de diálogo creado por el función Crear.

Cuestiones relacionadas