【问题标题】:c++ 11 lambda usage as delegate with std::functionc++ 11 lambda 用作 std::function 的委托
【发布时间】: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&lt;void()&gt; 取决于可能被破坏的对象,也许您可​​以让您的函数对象为 std::function&lt;void(Button &amp;)&gt; 类型,以便您也可以显式传递按钮。
  • 感谢 cmets。 @EdMaster,我知道你的担心,我保证“this”指针是有效的,因为它是我在应用程序中的当前屏幕并且正在积极渲染。

标签: c++ c++11 lambda callback


【解决方案1】:

你不能打电话吗:

   button->setClickListener([this]()->void {
      // Do something
      memberFunction();
      anotherMemberFunction();
      // etc...
   });

在构造函数中或在您的应用程序代码上的任何其他初始化方法中?

此外,您的代码可以获得右值引用。

void setClickListener(OnClickListener&& callback);

【讨论】:

  • 感谢您的努力,但我的监听器在应用程序的生命周期中会根据处理的事件发生变化。
猜你喜欢
  • 2012-09-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-11-19
  • 1970-01-01
  • 2022-01-23
相关资源
最近更新 更多