构造执行派生类成员函数的线程

Constructing thread executing a member function of a derived class

本文关键字:函数 线程 成员 执行 派生      更新时间:2023-10-16

我有两个相互继承的类BaseDerived。在Base中,我想创建一个执行类的成员函数Handle的线程(TThread是ROOT的MT库)。我想在Derived中重写这个句柄函数,但是我的程序总是从基类而不是从派生类执行函数。我如何更改它,以便执行被覆盖的句柄?

代码如下:

#include "TThread.h"
#include <iostream>
using namespace std;
class Base
{
public:
    Base()
    {
        thread = new TThread("BaseClass", (void(*)(void*))&Handle,(void*)this);
        thread->Run();
    }
private:
    TThread *thread;
    static void* Handle(void *arg)
    {
        cout<<"AAAA"<<endl;
    }
};
class Derived : public Base
{
public:
    Derived() : Base(){}
private:    
    static void* Handle(void *arg)
    {
        cout<<"BBBB"<<endl;
    }
};

int main()
{   
    Derived *b = new Derived();
    return 0;
}

您试图在非virtual函数上实现多态性。

在基类构造函数中对Handle的引用在编译时被解析为始终指向Base::Handle,无论该对象在运行时的具体类型是什么。这可以通过将Handlestatic函数更改为virtual函数来修复。

另一个问题是,您试图从基类构造函数创建线程。此时,派生对象还没有完全构造好,因此即使将其更改为virtual函数,也不能以多态方式分派到Derived::Handle。一个快速的解决方案是将线程构造移动到Base::startThread()方法中,并在构造函数返回后调用该方法。

使Handle像@ComicSansMS所说的那样是虚拟的,并引入一个静态成员函数来正确处理虚拟分派:

#include "TThread.h"
#include <iostream>
using namespace std;
class Base
{
public:
    Base() : thread() {}
    ~Base() { wait(); }
    void wait() {
        if (thread)
        {
            thread->Join();
            delete thread;
            thread = NULL;
        }
    }
    void start()
    {
        thread = new TThread("BaseClass", &Dispatch, this);
        thread->Run();
    }
private:
    TThread *thread;
    virtual void Handle()
    {
        cout<<"AAAA"<<endl;
    }
    static void* Dispatch(void *arg)
    {
        static_cast<Base*>(arg)->Handle();
        return NULL;
    }
};
class Derived : public Base
{
public:
    Derived() { start(); }
    ~Derived() { wait(); }
private:
    virtual void Handle()
    {
        cout<<"BBBB"<<endl;
    }
};

int main()
{   
    Derived b;
}