如何在线程对象中调用多态方法?
Posted
技术标签:
【中文标题】如何在线程对象中调用多态方法?【英文标题】:How to call a polymorphic method in a thread object? 【发布时间】:2021-10-29 10:42:36 【问题描述】: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)
// Compile error
// expecting Derived_A and Derived_B do_work functions to be called respectively
threads.emplace_back(&Base::do_work, worker);
在线程中调用do_work()
方法的正确方法是什么?
【问题讨论】:
threads.emplace_back(&Base::do_work, std::ref(*worker));
编译但需要进一步调查智能指针的所有权。直播 - godbolt.org/z/q3W7jejof
Re: //Compile error
-- 当然编译器说的不止这些。
@PeteBecker 公平地说,有时编译时错误很难破译。无论如何,在显示复杂的“数据结构”之后(可视化 c++ 实现),最终错误是这样的: “无法将参数 1 从 '_Ty' 转换为 'std::allocator_arg_t'”
【参考方案1】:
多态应该正常工作,因为指向虚成员函数的指针在调用时总是表现出多态性。只需进行两项更改即可使您的程序正确:
-
创建线程时必须写
worker.get()
。这是因为指向成员函数 Base::do_work
的指针是“可调用的”,其参数是指向 Base
的指针,但您不能直接将智能指针“传递”给它。
您必须记住在main
结束之前分离或加入线程。
【讨论】:
以上是关于如何在线程对象中调用多态方法?的主要内容,如果未能解决你的问题,请参考以下文章