Virtual method & this pointer
I'm just beginning to learn C++ and I'm trying to make Thread class that that has the basic functionality of the Java Thread class. What I'm trying to do is make a class which you subclass, write a Run method (which is pure virtual in the base class) create an object of the subclass call the start method on it and you have thread.
The problem is that in the way I use C++ the dispatch isn't done correctly - it's like the Run function isn't virtual, the Run method of the base class is called.
Here is the code for the header
#ifndef _THREAD_H_
#define _THREAD_H_
#include <pthread.h>开发者_JS百科;
class Thread {
public:
Thread();
void Start();
~Thread();
protected:
virtual void Run() = 0;
private:
static void *RunWrapper(void *);
pthread_t thread;
};
#endif
The implementation
#include "thread.h"
#include <pthread.h>
Thread::Thread() {
}
void Thread::Start() {
pthread_create(&thread, NULL, Thread::RunWrapper, (void *) this);
}
void *Thread::RunWrapper(void *arg) {
Thread *t = (Thread *) arg;
t->Run();
return arg;
}
Thread::~Thread() {
pthread_join(thread, NULL);
}
And the file that actually tries to do something
#include <iostream>
#include "thread.h"
class MyThread : public Thread {
protected:
void Run() {
std::cout << "The thread is runned" << std::endl;
}
};
int main(void) {
MyThread thread;
thread.Start();
return 0;
}
The error I keep getting for the last 10 hours is:
pure virtual method called
terminate called without an active exception
The problem is that your MyThread object in main is destroyed as soon as the main function returns, which likely happens before the new thread actually gets around to calling its Start method.
As part of the destruction process, the vtable will be reset to the vtable of the base class before calling the base class destructor, so when the RunWrapper call later gets run it ends up triggering the pure virtual method error. Calling a method on a destroyed object results in undefined behavior, so anything might happen; this behavior is an accident of how your C++ compiler implements destructors and stack allocation.
Not certain what's causing the error directly, but what you're doing is bad: your MyThread object can go out of scope before your thread accesses it. It's entirely possible the scope is gone and the pointer is invalid by the time your thread starts processing.
Try allocating your object on the heap, and see if it works (then, assuming it does, figure out how to free the object when the thread is done).
Oh, and you'll want to next exit your app (by returning from main) until your thread is done also...
The problem is that you are calling Start, which belongs to the Thread class. This method is then calling Run, which will call the Run method of the Thread class. Unfortunately, you cannot call the overrided method from the base class.
精彩评论