This question already has an answer here:
- c++ , pthread and static callbacks. “this” returns a pointer to the base class inctead of the derived one (part 2) 1 answer
I am using as basis this cpp thread class. This I use as a base class for threads. Note that in my case Thread::main() is a virtual function (unlike in the link). So I basically use:
class Thread {
public:
virtual void main()
{
cout << "This should not be run once derived and redefined." << endl;
}
void run()
{
pthread_create(&thread, 0, &callback, this);
}
pthread_t thread;
}; // class Thread
void* callback(void* obj)
{
static_cast<Thread*>(obj)->main();
return(0);
} // callback
Then I create a derived class and re-define the myThreadedClass::main()
member to actually do something meaningful.
Finally, I instantiate the myThreadedClass object from other classes or my main function call as follows:
main(int argc, char** argv){
myThreadedClass thr;
thr.run();
//do other stuff
}
This works fine; The callback function gets a pointer to the derived class instantiation, so the myThreadedClass::main()
gets executed.
However, I now try to create a different derived class class otherThreadClass : public Thread
. Again I re-define my otherThreadClass::main()
, but now I have a member function in the derived class which (unlike before) calls Thread::run().
class otherThreadClass : public Thread{
public:
writeToDiskAsync(string& str){
prepareString(str);
//spawn a thread to carry the write without blocking execution
run();
}
};
in this case from my main function I do
main(int argc, char** argv){
otherThreadClass thr;
thr.writeToDiskAsync(aString);
//do other stuff
}
The problem in this case is that the callback function gets a pointer to the Thread class and the Thread::main() ends up being executed instead of the otherThreadClass::main().
I tried passing a pointer to the instantiated myThreadedClass object during instantiation (using initialisation lists and an altered call to Thread::run(void* instance)) as follows
//in main function
otherThreadClass thr(&thr);
//in class
otherThreadClass::otherThreadClass(otherThreadClass* ptr):instancePtr(ptr)
{}
otherThreadClass::writeToDiskAsync(string& str)
{
//do stuff
run(instancePtr);
}
//and finally
Thread::run(void* parentObj)
{
pthread_create(&thread, 0, &callback, parentObj);
}
but it does not work. And I think this is probably not a nice way to do it anyway. So what can I do to let the callback function get apointer to the derived class instance instead of the base class ?
thank you