深入理解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版本的,你深入进去找,它就是这么干的。

posted on 2019-09-03 10:17  litandy  阅读(287)  评论(0编辑  收藏  举报

导航