gc型语言转c++的一般会踩这个坑
【 在 Algoquant 的大作中提到: 】
: 标 题: lambd表达式对已析构对象为啥不抛异常
: 发信站: 水木社区 (Fri Jan 26 22:40:57 2024), 站内
:
: 把对象捕获绑定在lambda表达式里,对象已经析构了,在调用lambda时不抛异常,按UB处理,这是大坑啊。
:
: 我发现对这种情况,只能用 enable_share_from_this 来搞,把对象指针shared_ptr<T>托管到队列或者数组里,异步适时再调用该对象的成员函数。 (我的场景:每个算法对象订阅行情,并在收行情数据后调度器按每个股票快照 调用每个算法对象的onMarketDepth(const MarketDepth& m
: d),这里面就涉及每次调度时,算法对象算法是否还存活)
:
: #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;
: }
:
: --
:
: ※ 来源:·水木社区
http://www.mysmth.net·[FROM: 113.91.210.*]
--
FROM 223.72.88.*