如何在线程对象中调用多态方法?

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(&amp;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 结束之前分离或加入线程。

【讨论】:

以上是关于如何在线程对象中调用多态方法?的主要内容,如果未能解决你的问题,请参考以下文章

22. 啥是多态?

多态的绑定机制

多态的深入理解

多态父类引用指向子类对象时,如何调用子类的独有方法?

Python中的多态如何理解?(转帖,让我很理解。)

面向对象 多态