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
相关产品推荐
相关产品推荐

