未从线程调用重写的虚函数

时间:2019-08-16 04:05:53

标签: multithreading c++11

我正在编写一个基类来管理线程。这个想法是允许在子类中重写线程函数,而基类管理线程生命周期。我遇到了一个我不理解的奇怪行为-似乎是从线程进行调用时,虚函数机制无法正常工作。为了说明我的问题,我将代码简化为以下内容:

#include <iostream>
#include <thread>

using namespace std;

struct B
{
    thread t;
    void thread_func_non_virt()
    {
        thread_func();
    }

    virtual void thread_func()
    {
        cout << "B::thread_func\n";
    }

    B(): t(thread(&B::thread_func_non_virt, this)) { }
    void join() { t.join(); }
};

struct C : B
{
    virtual void thread_func() override
    {
        cout << "C::thread_func\n";
    }
};

int main()
{
    C c;   // output is "B::thread_func" but "C::thread_func" is expected
    c.join();
    c.thread_func_non_virt();   // output "C::thread_func" as expected
}

我尝试使用Visual Studio 2017和g ++ 5.4(Ubuntu 16),发现行为是一致的。有人可以指出我错了吗?

==更新==

基于Igor的回答,我将线程创建从构造函数中移出到一个单独的方法中,并在构造函数之后调用该方法,并获得了所需的行为。

2 个答案:

答案 0 :(得分:4)

您的程序显示未定义的行为。 *thisthread_func(隐式定义)的构造函数之间在C上存在竞争。

答案 1 :(得分:0)

#include <iostream>
#include <thread>
using namespace std;

struct B
{
    thread t;
    void thread_func_non_virt()
    {
        thread_func();
    }

    virtual void thread_func()
    {
        cout << "B::thread_func\n";
    }

    B(B*ptr): t(thread(&B::thread_func_non_virt, ptr))
    {
    }
    void join() { t.join(); }
};
struct C:public B
{
    C():B(this){}
    virtual void thread_func() override
    {
        cout << "C::thread_func\n";
    }
};



int main()
{
    C c;   //  "C::thread_func" is expected as expected
    c.join();
    c.thread_func_non_virt();   // output "C::thread_func" as expected
}
相关问题