我有以下代码:
void MyClass::onOpenModalBtnClicked() {
uiManager->load(L"data/ui/testmodal.json");
std::shared_ptr<UIElement> modal = uiManager->getElementById("loginModal");
if(modal) {
modal->getElementById("closeButton")->onClicked = [modal]() {
modal->hide();
};
}
}
这工作正常,当单击按钮时模式关闭,onClicked
是一个std::function
.
我的应用程序开头也有这个:
#if defined(DEBUG) | defined (_DEBUG)
_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
#endif
当应用程序终止时,这会打印出内存泄漏。
使用上面的代码,我得到了很多内存泄漏,如果我将代码更改为下面,它们都消失了:
void MyClass::onOpenModalBtnClicked() {
uiManager->load(L"data/ui/testmodal.json");
std::shared_ptr<UIElement> modal = uiManager->getElementById("loginModal");
if(modal) {
modal->getElementById("closeButton")->onClicked = [this]() {
uiManager->getElementById("loginModal")->hide();
};
}
}
我假设传入shared_ptr
by 值会将引用计数增加 1,然后此引用永远不会超出范围,或者在报告内存泄漏后它会超出范围。因此,我在使用 shared_ptr 后尝试在 lambda 中调用 reset 但随后出现此编译器错误:
Error 1 error C2662: 'void std::shared_ptr<_Ty>::reset(void) throw()' : cannot convert 'this' pointer from 'const std::shared_ptr<_Ty>' to 'std::shared_ptr<_Ty> &'
所以问题是我怎样才能使用捕获的modal
而不是得到那些内存泄漏?
编辑:mutable
所以我通过添加到 lambda 来
摆脱编译错误。
if(modal) {
modal->getElementById("closeButton")->onClicked = [modal]() mutable {
modal->hide();
modal.reset();
};
}
现在,如果我单击关闭按钮并关闭应用程序,则不会出现内存泄漏,因为重置会清除该引用。但是,如果从未单击该按钮,我仍然会泄漏。