如何优雅实现C++嵌套future结构?多层异步驱动依赖设计咨询
问题解答
1. 更优的实现方案
你需要的是**future延续(continuation)**设计模式,完全不需要自己封装独立的Future持有类。
如果你的编译环境支持C++20,直接用std::future<T>::then就可以在I2C层返回的future后挂载解析逻辑,直接返回标准的std::future<double>,示例代码如下:
std::future<double> PCT2075::getTemperature() { // 调用I2C层接口拿到原始数据的future auto i2c_future = i2c_read(/* PCT2075对应的读寄存器参数 */); // 挂载延续逻辑,I2C操作完成后自动执行解析 return std::move(i2c_future).then([](std::future<std::pair<std::vector<uint8_t>, bool>> f) { auto [raw_data, read_ok] = f.get(); if (!read_ok) throw std::runtime_error("I2C read failed"); // 原始字节转温度的解析逻辑 int16_t raw_temp = (static_cast<int16_t>(raw_data[0] << 8) | raw_data[1]) >> 5; return raw_temp * 0.125; }); }
如果使用的是C++11/17,没有内置then方法,也可以用std::async封装实现同等效果,同样可以直接返回std::future<double>:
std::future<double> PCT2075::getTemperature() { auto i2c_future = std::make_shared<std::future<std::pair<std::vector<uint8_t>, bool>>>( i2c_read(/* 读寄存器参数 */) ); return std::async(std::launch::deferred, [i2c_future]() { auto [raw_data, read_ok] = i2c_future->get(); if (!read_ok) throw std::runtime_error("I2C read failed"); // 同上的解析逻辑 int16_t raw_temp = (static_cast<int16_t>(raw_data[0] << 8) | raw_data[1]) >> 5; return raw_temp * 0.125; }); }
该方案天然兼容多future依赖的场景:只需要在延续逻辑里依次调用多个I2C future的get()方法,等所有I2C操作完成后统一解析即可。
2. 让TemperatureFuture继承std::future是否合理?
不建议这么做,你听到的最佳实践是对的:
std::future没有虚析构函数,继承后如果用基类指针指向子类对象,销毁时会出现内存泄漏std::future的设计初衷是作为值类型传递,并非用来做基类扩展,继承反而会提升代码复杂度和后续维护成本
3. 现有实现是否需要调整?
你目前的包装类实现功能上是可用的,但不属于业内常规做法。常规方案是基于future延续逻辑直接返回标准库的future类型,上层不需要适配你自定义的TemperatureFuture类型,通用性更好,代码也更简洁。如果你的开发环境支持C++11以上标准,建议换成延续方案。
内容的提问来源于stack exchange,提问作者Frodyne
相关产品推荐
相关产品推荐

