把对象捕获绑定在lambda表达式里,对象已经析构了,在调用lambda时不抛异常,按UB处理,这是大坑啊。
我发现对这种情况,只能用 enable_share_from_this 来搞,把对象指针shared_ptr<T>托管到队列或者数组里,异步适时再调用该对象的成员函数。 (我的场景:每个算法对象订阅行情,并在收行情数据后调度器按每个股票快照 调用每个算法对象的onMarketDepth(const MarketDepth& md),这里面就涉及每次调度时,算法对象算法是否还存活)
#include <iostream>
#include <memory>
#include <thread>
#include <vector>
#include <functional>
class MyClass {
public:
MyClass(int i):m(i) {
std::cout << "----MyClass::MyClass() " << m << std::endl;
}
void member_function() {
std::cout << "****I am still alive! " << m << std::endl;
}
~MyClass() {
std::cout << "----MyClass::~MyClass() " << m << std::endl;
}
int m;
};
int main() {
std::vector<std::function<void()>> v_f;
{
for (auto& i : { 2,4,6 }) {
std::shared_ptr<MyClass> my_class = std::make_shared<MyClass>(i);
auto lambda = [my_class]() {
my_class->member_function();
};
std::cout << i << " lambda name() = " << typeid(lambda).name() << std::endl;
std::cout << i << " lambda.address() = " << &lambda << std::endl;
v_f.push_back(lambda);
}
}
{
for (auto& i : { 1,3,5}) {
MyClass my_class{i};
auto lambda = [&my_class]() {
my_class.member_function();
};
std::cout << i << " lambda name() = " << typeid(lambda).name() << std::endl;
std::cout << i << " lambda address() = " << &lambda << std::endl;
v_f.push_back(lambda);
}
}
for (auto& task : v_f) { // 1 3 5 已经析构了,居然还能跑, 最后一个数据还正确.... 这隐藏坑
task();
}
return 0;
}
--
FROM 113.91.210.*