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

Sono abbastanza sicuro che queste perdite. Quello che sto veramente chiedendo è: c'è qualche "magia" in MFC che pulisce il dialogo quando la finestra di dialogo viene distrutta. Come funzionerebbe se dlg non fosse un puntatore ma dichiarato sullo stack - non sarebbe il distruttore a distruggere la finestra quando dlg andrebbe fuori ambito.Si tratta di una perdita di memoria in MFC

risposta

12

sì, è perdita di memoria nel tuo caso, ma si può evitare perdita di memoria nei casi in cui dialogo non modale allocato sul mucchio facendo uso di rilevante PostNcDestroy.

Le finestre di dialogo non sono progettate per la pulizia automatica (dove come finestre del fotogramma principale, le finestre di visualizzazione sono). Nel caso in cui si desideri fornire la pulizia automatica delle finestre di dialogo, è necessario sostituire la funzione membro PostNcDestroy nella classe derivata. Per aggiungere la pulizia automatica alla classe, chiamare la classe base e quindi fare una delete this. Per rimuovere la cancellazione automatica dalla classe, chiamare direttamente CWnd::PostNcDestroy anziché il membro PostNcDestroy nella classe di base diretta.

void MyDialog::PostNcDestroy() 
{ 

    CDialog::PostNcDestroy(); 
    delete this; 
} 

Come funziona (da MSDN):

Quando distruggendo una finestra di Windows, l'ultimo messaggio di Windows inviato alla finestra è WM_NCDESTROY. Il gestore predefinito CWnd per quel messaggio (CWnd :: OnNcDestroy) scollega l'HWND dall'oggetto C++ e chiama la funzione virtuale PostNcDestroy. Alcune classi sostituiscono questa funzione con elimina l'oggetto C++.

"elimina questo" libera qualsiasi memoria C++ associata all'oggetto C++. Anche se le chiamate distruttore predefinito CWnd DestroyWindow se m_hWnd è non-NULL, ciò non porta a ricorsione infinita poiché la maniglia viene staccato e NULL durante la fase pulitura.

È anche possibile consultare MSDN (Destroying Window Objects) per ulteriori dettagli.

Nota:

Questo funziona per il dialogo non modale che può essere allocata sul mucchio.

3

Sì, è una perdita. E sì, la finestra verrebbe distrutta se l'oggetto fosse allocato allo stack. L'utilizzo delle finestre di dialogo come oggetti allocati nello stack è tipico delle finestre di dialogo modali: si chiama un metodo per mostrare una finestra di dialogo come una finestra modale e tale metodo restituisce solo quando la finestra di dialogo viene chiusa e l'oggetto viene distrutto.

+0

Grazie. Ho dimenticato di dire che questo è per una finestra di dialogo Modeless. Presumo che in questo caso per la pulizia l'oggetto di dialogo debba essere una variabile membro, quindi può essere distrutto/de-allocato nel distruttore dei frame. – Richard

2

Se si chiama manualmente Create su una finestra di dialogo, è necessario manualmente Destroy esso pure.
Quando si utilizza DoModal() non è necessario.

Da MSDN:

Utilizzare la funzione di CWnd :: DestroyWindow per distruggere una finestra di dialogo creata dal funzione Crea.