You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何优雅实现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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.25 11:45:05