构造执行派生类成员函数的线程
Constructing thread executing a member function of a derived class
我有两个相互继承的类Base
和Derived
。在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
,无论该对象在运行时的具体类型是什么。这可以通过将Handle
从static
函数更改为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;
}
相关文章:
- 如何将元素添加到数组的线程安全函数?
- C++Boost Asio Pool线程,带有lambda函数和传递引用变量
- C++使用params创建线程函数会导致转换错误
- 为什么std::async使用同一个线程运行函数
- 使用 std::string () const 函数启动线程或未来
- C++线程中,没有重载函数接受 X 参数
- 如何从线程中的不同模块调用函数?
- 如何在调用析构函数时优雅地停止/销毁带有阻塞调用C++线程?
- 使用带有 ref 参数的成员函数创建线程时出现编译错误
- 如何将类的成员函数传递给线程
- 是否可以创建一个从不同类调用函数的线程?
- 如何制作一个只能在一个线程上同时执行的函数?
- 启动类函数作为失去引用的线程
- 为什么即使调用了析构函数,C++11 中的分离线程也可以执行
- 非静态成员失败的线程调用函数
- 线程调用的函数对对象删除是否安全?
- 将类成员函数作为线程调用到另一个类成员函数时发出警告消息
- 类成员在构造函数(线程)之后更改地址
- C++无限依次运行两个函数(线程)
- c++将各种参数传递给父类构造函数(线程c++11)