【发布时间】:2016-12-14 17:59:51
【问题描述】:
我有一个 Button 类,它有一个 onClick std::function 类型字段,“setClickListener”方法将任何 lambda 函数设置为这个 std::function 字段,如下所示:
#include <functional>
class Button {
public:
void doSomething() {
if(onClick) {
onClick();
}
}
typedef std::function<void()> OnClickListener;
OnClickListener onClick;
void setClickListener(OnClickListener onClickCallBack) {
onClick = onClickCallBack;
}
};
在我的应用程序代码中,我正在创建一个 lambda 函数并设置为按钮的 onClick 函数,如下所示:
#include "Button.h"
void onAnEventOccured() {
button->setClickListener([this]()->void {
// Do something
memberFunction();
anotherMemberFunction();
// etc...
});
}
void memberFunction() {
// Do some work...
}
void anotherMemberFunction() {
// Do some work...
}
现在,关键部分是在应用程序的生命周期中多次调用 onAnEventOccured 方法,并且一次又一次地设置 lambda 函数。我在 Visual Studio 2015 上运行并将调试跟踪点放在 std::function 类的解构器上,并且可以在设置 setClickListener 时看到它命中跟踪点。我猜这是 lambda 函数的解构函数,它在离开 onAnEventOccured 函数的范围时被破坏,并且该 lambda 的复制版本按预期存储在 Button 实例中。
我在这方面是正确的吗?此架构是否存在内存泄漏?
【问题讨论】:
-
您的两个问题似乎完全正交。就析构函数的跟踪点而言,它可能是在将您的 lambda 又名匿名对象转换为 std::function 对象时创建的临时
std::function对象,而不是匿名对象又名 lambda 的析构函数。 -
没有内存泄漏,临时对象被销毁。我无法回答您的其他问题,因为您的第二段代码无效,因为您尝试在成员函数之外使用
this。如果我理解您尝试做什么,您将有一个std::function<void()>取决于可能被破坏的对象,也许您可以让您的函数对象为std::function<void(Button &)>类型,以便您也可以显式传递按钮。 -
感谢 cmets。 @EdMaster,我知道你的担心,我保证“this”指针是有效的,因为它是我在应用程序中的当前屏幕并且正在积极渲染。