深入理解lambda表达式
#include "stdafx.h"
#include <memory>
#include <iostream>
#include <functional>
class AObject
//: public std::enable_shared_from_this<AObject>
{
public:
AObject() : m_i(0)
{
std::cout << "AObject construct" << std::endl;
}
virtual ~AObject()
{
std::cout << "AObject distruct" << std::endl;
}
void test()
{
if (m_callback){
m_callback();
}
}
template<typename F>
void setCallback(F f)
{
m_callback = f;
}
private:
int m_i;
std::function<void()> m_callback;
};
int _tmain(int argc, TCHAR* argv[])
{
std::shared_ptr<AObject> pAObject(new AObject());
std::cout << "after constructing count is " << pAObject.use_count() << std::endl;
pAObject->setCallback(
//[&pAObject](){
[pAObject](){
std::cout << "in callback count is " << pAObject.use_count() << std::endl;
//pAObject->~AObject();//你传值进来的共享指针,需要自行调用析构
}
);
std::cout << "after setting callback count is " << pAObject.use_count() << std::endl;
int ii;
for (ii = 0; ii < 5;ii++){
pAObject->test();
}
return 0;
}
输出的结果是:
AObject construct
after constructing count is 1
after setting callback count is 2
in callback count is 2
in callback count is 2
in callback count is 2
in callback count is 2
in callback count is 2
如果解开
//[&pAObject](){
这行的注释,并注释掉下一行
[pAObject](){
执行的结果是
AObject construct
after constructing count is 1
after setting callback count is 1
in callback count is 1
in callback count is 1
in callback count is 1
in callback count is 1
in callback count is 1
AObject distruct
结论
1. lambda表达式的闭包列表中的变量如果是传值的,确实是传值的,如果将共享指针放入闭包列表,会使共享指针引用计数加1。
2. lambda表达式类似定义了一个类,闭包列表中的变量,类似这个类中的静态变量,定义之后被初始化,只初始化一次。
3. lambda表达式每次执行,类似实例化了一个对象,把函数体作为构造函数执行,构造函数的参数列表就是lambda表达式的参数列表就是。
4. lambda表达式设置好了就一直存在,你看第一种情况下程序都退出了,还是没有释放AObject对象。你需要自行减少引用计数,方法是调用一下析构函数。
你可以将
//[&pAObject](){
这行继续注释掉,并放开
[pAObject](){
和
// pAOjbect->~AObject();
这2行的注释,执行结果是
AObject construct
after constructing count is 1
after setting callback count is 2
in callback count is 2
AObject distruct
AObject distruct
最后2行,第一行是手动执行析构,而打印出第一句,而第二句是程序结束时,因为引用计数为0,自动释放对象,而打印出来的。
很有意思,std::asio代码的例子程序c++11版本的,你深入进去找,它就是这么干的。
浙公网安备 33010602011771号