Search code examples
c++boostboost-thread

boost thread destroys polymorphism


duplicate of: "pure virtual method called" when implementing a boost::thread wrapper interface

I am trying to create a more object oriented version of the threads using boost threads.

So I created a Thread class:

class Thread {
public:
    Thread() {}
    virtual ~Thread() { thisThread->join(); }

    void start() { thisThread = new boost::thread(&Thread::run, this); }

    virtual void run() {};

private:
    boost::thread *thisThread;
};

this class creates the thread in start() like this:

thisThread = new boost::thread(&Thread::run, this);

The problem is that when I create a class that overwrites the run() method, the run() method from Thread is call by the thread instead of the new run() method

for example I have a class that extends Thread:

class CmdWorker: public Thread {
public:
    CmdWorker() : Thread() {}
    virtual ~CmdWorker() {}

    void run() { /* deosn't get called by the thread */ }
};

when I do

Thread *thread = new CmdWorker();
thread.start(); //---> calls run() from Thread instead of run() from CmdWorker

but just to be more clear:

thread.run();  calls the correct run from CmdWorker, (run() is virtual from Runnable)

Any idea why this happens or how it can be fixed ?

NOTE: I created a function (that has nothing to do with the Thread class)

void callRun(Thread* thread) {
    thread->run();
}

and changed the thread creation to:

thisThread = new boost::thread(callRun, this);

when debugging I noticed that the thread pointer is pointing to a object of type Thread instead of CmdWorker

EDIT:

testcase code at: http://ideone.com/fqMLF and http://ideone.com/Tmva1

Object seems to be sliced (but this is strange since pointers are used)

didn't manage to add boost to it


Solution

  • The answer is in that question:

    "pure virtual method called" when implementing a boost::thread wrapper interface

    Basically, when the boost::thread object begins running, the object it was run against had the time to be deleted.

    You have to implement a join method that you call manually before destroying the object.