副本:"pure virtual method called" when implementing a boost::thread wrapper interface
我正在尝试使用boost线程创建一个更面向对象的线程版本。
所以我创建了一个Thread类:
class Thread {
public:
Thread() {}
virtual ~Thread() { thisThread->join(); }
void start() { thisThread = new boost::thread(&Thread::run, this); }
virtual void run() {};
private:
boost::thread *thisThread;
};
这个类在start()中创建线程 像这样:
thisThread = new boost::thread(&Thread::run, this);
问题在于,当我创建一个覆盖run()
方法的类时,线程中的run()
方法是由线程调用而不是新的run()
方法
例如我有一个扩展Thread的类:
class CmdWorker: public Thread {
public:
CmdWorker() : Thread() {}
virtual ~CmdWorker() {}
void run() { /* deosn't get called by the thread */ }
};
当我做的时候
Thread *thread = new CmdWorker();
thread.start(); //---> calls run() from Thread instead of run() from CmdWorker
但是要更清楚:
thread.run(); calls the correct run from CmdWorker, (run() is virtual from Runnable)
知道为什么会这样或者如何修复它?
注意: 我创建了一个函数(与Thread类无关)
void callRun(Thread* thread) {
thread->run();
}
并将线程创建更改为:
thisThread = new boost::thread(callRun, this);
调试时我注意到thread
指针指向Thread类型的对象而不是CmdWorker
编辑:
testcase代码:http://ideone.com/fqMLF 和http://ideone.com/Tmva1
对象似乎被切片(但由于使用了指针,这很奇怪)
无法为其添加提升
答案 0 :(得分:4)
答案就是那个问题:
"pure virtual method called" when implementing a boost::thread wrapper interface
基本上,当boost :: thread对象开始运行时,它运行的对象有了 时间被删除。
您必须实现在销毁对象之前手动调用的join
方法。
答案 1 :(得分:3)
调试时我注意到线程指针指向一个 Thread类型的对象而不是CmdWorker
也许CmdWorker
对象被切片(即按值复制)到代码中的某个Thread
对象中?
您是否在最小的测试用例中获得相同的行为?
答案 2 :(得分:2)
从读取更新开始,您将在主线程中调用delete,而线程在另一个线程中启动。根据析构函数和run
的调用之间的竞争,它将:
如果您在致电开始后拨打sleep(1)
电话,但在致电delete
之前,您会发现它可以正常运作。
答案 3 :(得分:1)
通过对非虚函数执行&Thread::Run
,您强制从Thread派生的任何类使用Thread基类中指定的函数。尝试使Thread :: Run成为虚拟空白,看看是否能解决您的问题。