我有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
帧时,它会自动销毁它,但指针仍然引用旧地址,我无法控制从此客户端代码中销毁帧。
如何取消引用指向已销毁帧的指针?
答案 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之外,这意味着一些额外的信息。