简体   繁体   English

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

[英]Constructing thread executing a member function of a derived class

I have two classes Base and Derived inheriting from each other. 我有两个互相继承的BaseDerived类。 In Base I want to create a thread executing the member function Handle of the class ( TThread is MT library of ROOT). Base我想创建一个执行成员函数Handle的线程( TThread是ROOT的MT库)。 I want to override this handle function in Derived , but my program always executes the function from the base class rather than the one from the derived class. 我想在Derived重写此句柄函数,但是我的程序始终从基类执行该函数,而不是从派生类执行该函数。 How can I change it so that the overridden Handle is executed instead? 我该如何更改它以便改写覆盖的句柄?

Here is the code: 这是代码:

#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;
}

You are trying to achieve polymorphism with on a non- virtual function. 您正在尝试通过非virtual函数实现多态。

The reference to Handle in your base class constructor gets resolved at compile time to always point to Base::Handle , no matter what the concrete type of the object at runtime will be. 基类构造函数中对Handle的引用会在编译时解析为始终指向Base::Handle ,无论对象在运行时的具体类型是什么。 This can be fixed by changing Handle from a static to a virtual function. 可以通过将Handlestatic功能更改为virtual功能来解决此问题。

The other problem is that you are trying to create the thread from the base class constructor. 另一个问题是您试图从基类构造函数创建线程。 The derived object has not been fully constructed at this point, so you cannot polymorphically dispatch to Derived::Handle , even if you change it to a virtual function. 此时,派生对象尚未完全构建,因此即使将其更改为virtual函数,也不能将其多态派发到Derived::Handle A quick solution for this would be to move the thread construction to a Base::startThread() method and call that after the constructor has returned. 一个快速的解决方案是将线程构造移至Base::startThread()方法,并在构造函数返回后调用该方法。

Make Handle virtual as @ComicSansMS says , and introduce a static member function to handle the virtual dispatch correctly: @ComicSansMS所说 ,将Handle虚拟 ,并引入一个静态成员函数来正确处理虚拟调度:

#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;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM