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

C++中如何在线程对象中正确调用多态成员函数?

问题原因分析
  • 参数类型不匹配:&Base::do_work是非静态类成员函数指针,调用时第一个入参要求为Base*类型的对象指针,原代码直接传入std::unique_ptr<Base>对象,类型不匹配触发编译错误。
  • 独占指针不可拷贝:std::thread构造函数默认会对传入的参数执行拷贝操作,而std::unique_ptr是独占所有权的智能指针,不支持拷贝语义,也会导致编译失败。
正确实现方案

两种常用写法都可以正常触发多态调用,效果一致:

方案1:传入底层对象指针

通过unique_ptr::get()获取原生Base*指针,匹配成员函数的入参要求:

#include <thread>
#include <vector>
#include <memory>

struct Base {
    virtual void do_work() = 0;
};

struct Derived_A : Base {
    void do_work() override {
        // work A
    }
};

struct Derived_B : Base {
    void do_work() override {
        // work B
    }
};

int main() {
    std::vector<std::unique_ptr<Base>> workers;
    workers.emplace_back(std::unique_ptr<Base>(new Derived_A()));
    workers.emplace_back(std::unique_ptr<Base>(new Derived_B()));

    std::vector<std::thread> threads;
    for (const auto& worker : workers) {
        threads.emplace_back(&Base::do_work, worker.get());
    }

    // 必须等待所有线程执行完成,避免程序提前退出触发未定义行为
    for (auto& t : threads) {
        t.join();
    }
    return 0;
}

方案2:Lambda包装调用逻辑

可读性更高,也方便扩展执行前后的自定义逻辑,仅需修改线程创建部分的代码:

for (const auto& worker : workers) {
    // 本示例中workers生命周期长于threads,按引用捕获无悬空风险
    threads.emplace_back([&worker](){
        worker->do_work();
    });
}
补充说明

两种写法都会正常触发虚函数多态,自动匹配Derived_A和Derived_B各自的do_work()实现。实际使用中需要保证workers容器的生命周期长于所有子线程的执行周期,避免出现悬空指针问题。

内容的提问来源于stack exchange,提问作者TosinAl

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 18:06:01