lambda延长生存期

lambda延长生存期

lambda作为类成员时,外部获取lambda后,在lambda作用于结束后,lambda会析构,
此时如果还有外部函数对象想继续使用lambda,本文提供了一种方法,可以通过延长lambda生存周期

主要方式是:
1:类继承enable_shared_from_this
2:类中通过self=shared_from_this() 将指针再包裹一次,增加引用计数

示例代码

#include <functional>
#include <iostream>
#include <vector>
#include <memory>
using namespace std;

struct TCPSession: public enable_shared_from_this<TCPSession>{
    int data;
	//更严谨的做法是此处定义为private,再用静态工厂创建,如果不是,创建的时候就要用share_ptr创建
    TCPSession(int d):data(d)	
    {
    }
    
    TCPSession(const TCPSession& rhs):data(rhs.data){
        cout<<"TCPSession copy ctor"<<endl;
    }
    
    void process() const{
        cout<<"process:"<<data<<endl;
    }

	//返回lambda表达式
     auto getLambda(){	//实现比较精妙,使用shared_from_this得到一个shared_ptr        
        //shared_ptr<TCPSession> self=make_shared<TCPSession>(this); 
         //错误!同一个指针被两个shared_ptr包装,可以一个shared_ptr被多个shared_ptr包装
		//本质是同一个裸指针被两个shared_ptr包装。
        shared_ptr<TCPSession> self=shared_from_this();//同一个shared_ptr被另外一个shared_ptr包装

        //必须有self,将this指针转shared_ptr并获取,此处捕获值捕获self后,shared_ptr引用+1
        auto lam=[this,self]() {	
            this->process();
            cout<<data<<endl;
        }; 
        return lam;
    }

    ~TCPSession(){
        cout<<"~TCPSession"<<endl;
    }
};

//非常常见需求:通过lamda表达式拽着shared_ptr的生命周期
int main(){
    std::function<void(void)> func;
    {
        shared_ptr<TCPSession> tsObj=make_shared<TCPSession>(100);	//此处必须shared_ptr
        
        func=tsObj->getLambda();
        cout<<tsObj->data++<<endl;

        func();

        cout<<tsObj->data++<<endl;
        cout<<"引用计数:"<<tsObj.use_count()<<endl;
    }//此处tsObj要析构
    
    func();//只有使用了shared_from_this,tsObj引用计数++,此处就可以继续使用
}

编译及结果

kongcb@tcu-pc:~/testcode/lambda$ g++ lambda_capture_this_share.cpp -o lambda_capture_this_share
kongcb@tcu-pc:~/testcode/lambda$ ./lambda_capture_this_share
100
process:101
101
101
引用计数:2
process:102
102
~TCPSession		//最后到这里才析构

错误分析

//如下使用lambda
auto getLambda(){
		auto lam=[ this]() mutable{
		this->process();	
		this->data++;
	};
	return lam;
}
//如上代码,this指向TCPSession不能阻挡share_ptr析构
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

技术的微光

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值