boost thread破坏了多态性

时间:2011-09-12 17:59:13

标签: c++ boost boost-thread

副本:"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/fqMLFhttp://ideone.com/Tmva1

对象似乎被切片(但由于使用了指针,这很奇怪)

无法为其添加提升

4 个答案:

答案 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的调用之间的竞争,它将:

  1. 启动前崩溃,因为vtable完全被破坏
  2. 调用Thread :: run(纯虚拟,并与纯虚拟thunk崩溃)
  3. 调用正确的函数,即派生类run()
  4. 如果您在致电开始后拨打sleep(1)电话,但在致电delete之前,您会发现它可以正常运作。

答案 3 :(得分:1)

通过对非虚函数执行&Thread::Run,您强制从Thread派生的任何类使用Thread基类中指定的函数。尝试使Thread :: Run成为虚拟空白,看看是否能解决您的问题。