【lambda表达式传值问题研究】

引用传值对象的声明周期会延长吗? —不会

#include <iostream>
#include <functional>

class Fun
{
public:
    std::function <int()> fun;
};

class Test
{
public:
    Test()
    {
        std::cout << "constructor" << std::endl;
    }
    ~Test()
    {
        std::cout << "destructor" << std::endl;
    }
    int num;
};

void function(Fun &obj)
{
    int num = 666;
    Test temp;
    temp.num = 888;
    obj.fun = [&]() ->int {
        std::cout << num << "," << temp.num << std::endl;
    };
}

int main()
{
    Fun test;
    function(test);
    test.fun();
    return 0;
}

输出:

constructor
destructor
666,32562 // 666能按原来的值输出只能说明原来那块地址没被使用<RETURN> 来关闭窗口...

=传值对象声明周期?

答在 labdm 这个对象消失后 释放

#include <iostream>
#include <functional>
#include <thread>

class Fun
{
public:
    Fun()
    {
        std::cout << "Fun::constructor" << std::endl;
    }
    ~Fun()
    {
        std::cout << "Fun::destructor" << std::endl;
    }
    std::function <int()> fun;
};

class Test
{
public:
    Test()
    {
        std::cout << "Test::constructor" << std::endl;
    }
    Test(const Test &obj)
    {
        num = 999;
        std::cout << "Test::copy_constructor" << std::endl;
    }
    ~Test()
    {
        std::cout << "Test::destructor" << std::endl;
    }
    int num;
};

void function(Fun &obj)
{
    int num = 666;
    Test temp;
    temp.num = 888;
    obj.fun = [=]() ->int {
        std::cout << num << "," << temp.num << std::endl;
        return 0;
    };
}

void test()
{
    Fun test;
    function(test);
    test.fun();
    std::cout << "test end" << std::endl;
}

int main()
{
    test();
    std::this_thread::sleep_for(std::chrono::seconds(600));
    return 0;
}


输出:

Fun::constructor
Test::constructor
Test::copy_constructor
Test::copy_constructor
Test::copy_constructor
Test::destructor
Test::destructor
Test::destructor
666,999
test end
Fun::destructor
Test::destructor

疑问1:这段代码为何调用3次Test的拷贝构造?

lambda表达式其实就是编译器给你生成了个对象,这个对象的一个成员就是=捕捉的变量,多以调用了一次拷贝构造,
在把这个lambda复制给一个function的时候由于类型不同。所以编译器的做法是 首先在等号右边把lambda构造一个临时的function对象调用了一次拷贝构造,然后把这个值复制给类的function成员变量又进行了一次调用了一次拷贝构造。

疑问2:=拷贝的对象内存在哪?栈空间还是堆空间?

拷贝的对象在lambda匿名对象里,它就是这个匿名对象的一个成员。这个lambda在哪它就在哪,如果&捕捉,编译器创建匿名对象的时候就用一个成员引用去对应这个捕捉的对象。
什么类不能拷贝构造?成员变量不能有:constexpr变量和引用类型,这个问题是面试的时候被问到的。当时不理解什么场景下类的成员要设计成引用,觉得这么设计很不安全。现在想想,可能就像这种工具类的应用场景下完美契合。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值