簡體   English   中英

取消引用指向不再存在的框架的指針

[英]Dereferencing a pointer to a frame that doesn't exist anymore

我有要控制其唯一性的MessagesViewer框架,

這段代碼:

MessagesViewer* m_pMsgViewer = NULL;

void Application::ShowMessagesViewer()
{
    if (m_pMsgViewer == NULL)
    {
        m_pMsgViewer = new MessagesViewer(
            wxGetApp().GetContainer()->GetAppData()->GetMessages()
        );
    }
    else
    {
        m_pMsgViewer->FillPage(wxGetApp().GetContainer()->GetAppData()->GetMessages());
        m_pMsgViewer->SetFocus();
    }
}

但是,當我第一次調用它時, m_pMsgViewer開始引用內存中的有效數據。 當我關閉MessagesViewer框架時,它會自動銷毀它,但是指針仍然指向舊地址,並且我無法控制從此客戶端代碼中銷毀該框架。

如何取消引用指向已破壞幀的指針?

一種解決方案是在關閉MessagesViewer時將m_pMsgViewer設置回nullptr 一種安全的方法是在框架中添加wxEVT_CLOSE_WINDOW的處理程序。 例如,將以下代碼添加到MessagesViewer的構造函數中:

Bind(wxEVT_CLOSE_WINDOW, [](wxCloseEvent& evt)
{
   m_pMsgViewer = nullptr;
   evt.Skip();
});

evt.Skip()使事件進一步傳播到wx提供的默認處理程序。

這個簡單的示例假定m_pMsgViewer是全局變量。 如果它實際上包含在Application對象中,則必須添加某種方式來訪問它。


將明顯的替代方法添加到MessagesViewer析構函數中並不是一個好主意,因為docs延遲了對MessagesViewer對象的實際銷毀,因此從理論上講Application::ShowMessagesViewer()可以調用FillPage()在已關閉並標記為要破壞但尚未實際破壞的框架上。

處理close事件會盡早重置指針,從而避免出現上述問題。

@bogdan已經提出了一個好的解決方案,但是還有另一個甚至更自動的解決方案:將幀指針存儲在wxWeakRef <>中 即保持與現在完全相同的代碼,但將聲明替換為

wxWeakRef<MessagesViewer> m_pMsgViewer;

銷毀窗口后,弱引用將自動重置為NULL

您需要以某種方式標記MessagesViwer已被破壞,無法再對其進行引用。 這意味着除了m_pMsgViewer之外,還有一些其他信息。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM