2015-07-11 565 views
2

在MFC中,對於典型的對話框窗口,當MFC調用OnOK()時,此函數調用EndDialog()函數,並在某個點調用類析構函數。在MFC中當調用EndDialog()時,類的析構函數什麼時候觸發?

假設我在CDialog的類中有一個名爲「test」的公共變量,並且在對話框OK按鈕的onBnClick()事件中,我將該「test」變量設置爲一個值。然後我聲明一個對話框的實例,並從我的主窗口的類中調用DoModal()。我可以讀取一次DoModal()返回的變量,沒有問題。

void Dialog1::OnBnClickedOk() 
{ 
    test = "The test string has been set."; 
    OnOK(); 
} 

void CMainFrame::OnEditTest() 
{ 
    Dialog1 dlg; 
    dlg.DoModal(); 
    MessageBox(dlg.test, L"Main Frm",0); 
} 

這是有效的,但是如果我有一個對話框有幾個字段和一個變量爲每個字段。我怎樣才能確定我可以在調用析構函數之前讀取所有變量的所有值?我檢查了MSDN,我的理解是OnOK()函數調用EndDialog(),並且在EndDialog()之後的某個時刻,類析構函數被調用。我希望始終能夠從OnBnClick()事件中設置的變量中讀取值,但我不清楚MFC何時調用類析構函數。有沒有人知道一旦EndDialog()觸發析構函數何時被觸發?

感謝, 突擊

+1

在上面的代碼中,'dlg'將保持有效,直到OnEditTest()返回。所以你有足夠的時間來讀取儘可能多的值。 –

+0

你碰巧知道何時調用析構函數? dlg從堆棧中移除時是否被調用?我無法在MSDN中找到此信息。 – Blitz

+0

Dialog1是一個常規的C++類,適用C++生命週期規則。 MSDN不記錄標準C++。 – IInspectable

回答

2

dlg.DoModal()回報,只有它的窗口句柄被銷燬。

dlg超出範圍時,將會調用析構函數。這部分與任何C++課程相同。

在您的示例中,當OnEditTest()返回時,dlg超出範圍。所以基本上你不必擔心,如果你犯了一個錯誤,編譯器會讓你知道。

爲了測試,你可以加上括號,並迫使dlg出去越早範圍:

void CMainFrame::OnEditTest() 
{ 
    { 
     Dialog1 dlg; 
     dlg.DoModal(); 
     MessageBox(dlg.test, L"Main Frm",0); 
    } 
    //dlg goes out of scope here and ~dlg() is called 

    //Next line will obviously not compile: 
    MessageBox(dlg.test, L"Main Frm",0); 
} 

作爲一個側面說明,你就必須要更加小心,如果你已經宣佈dlg爲指針。因爲您必須手動指示delete指針,並且指針在銷燬dlg()之後仍可以訪問。但這不是這種情況。

+0

我不知道簡單地將代碼封裝在括號內會導致它超出範圍,謝謝。 – Blitz

+0

因此,EndDialog在關閉時由CDialog窗口調用。每個MSDN:「EndDialog不立即關閉對話框,而是設置一個標誌,指示當前消息處理程序返回後立即關閉對話框。」在我的示例中,是「當前消息處理程序」,即擁有調用DoModal的方法的執行線程? – Blitz

+0

@閃電:花括號介紹[塊範圍](http://en.cppreference.com/w/cpp/language/scope)。這是基本的C++(和C)。 – IInspectable

相關問題