取消引用指向不再存在的帧的指针

时间:2015-05-18 05:48:59

标签: c++ wxwidgets

我有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帧时,它会自动销毁它,但指针仍然引用旧地址,我无法控制从此客户端代码中销毁帧。

如何取消引用指向已销毁帧的指针?

3 个答案:

答案 0 :(得分:2)

一个解决方案是在m_pMsgViewer关闭时将nullptr设置回MessagesViewer。一种安全的方法是为您的框架添加wxEVT_CLOSE_WINDOW的处理程序。例如,将以下代码添加到MessagesViewer的构造函数中:

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

evt.Skip()允许事件进一步传播到wx提供的默认处理程序。

这个简单的例子假设m_pMsgViewer是一个全局变量。如果它实际包含在Application对象中,则必须添加一些方法来访问它。

将此类代码添加到MessagesViewer析构函数这一明显的替代方案并不是一个好主意,因为MessagesViewer对象的实际销毁被延迟{{3因此,Application::ShowMessagesViewer()理论上可以在已关闭并标记为销毁但尚未实际销毁的框架上调用FillPage()

处理close事件会在早期重置指针,从而避免上述问题。

答案 1 :(得分:2)

@bogdan已经提出了一个很好的解决方案,但还有另一种更自动的方法:将帧指针存储在wxWeakRef<>中。即保持与现在完全相同的代码,但用

替换声明
wxWeakRef<MessagesViewer> m_pMsgViewer;

当窗口被破坏时,弱引用将自动重置为NULL

答案 2 :(得分:0)

您需要以某种方式标记MessagesViwer已被破坏且无法再引用。除了m_pMsgViewer之外,这意味着一些额外的信息。