У меня есть следующий код:
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
увеличивает счетчик ссылок на 1, а затем эта ссылка никогда не выходит за рамки видимости или выходит за рамки видимости после сообщения об утечках памяти. Поэтому я попытался вызвать сброс внутри лямбды после того, как я использовал shared_ptr, но затем я получил эту ошибку компилятора:
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
к лямбде.
if(modal) {
modal->getElementById("closeButton")->onClicked = [modal]() mutable {
modal->hide();
modal.reset();
};
}
Теперь, если я нажму кнопку закрытия и закрою приложение, утечек памяти не будет, так как сброс очищает эту ссылку. Но если кнопка никогда не нажимается, я все равно получаю утечки.