虚方法和这个指针

Joh*_* B. 1 c++ linux pthreads

我刚刚开始学习C++,我正在尝试使Thread类具有Java Thread类的基本功能.我正在尝试做的是创建一个你继承的类,编写一个Run方法(在基类中是纯虚拟的)创建一个子类的对象,在它上面调用start方法并且你有线程.

问题是,在我使用C++的方式中,调度没有正确完成 - 就像Run函数不是虚函数一样,调用了基类的Run方法.

这是标题的代码

#ifndef _THREAD_H_
#define _THREAD_H_

#include <pthread.h>

class Thread {
 public:
  Thread();

  void Start();

  ~Thread();

 protected:
  virtual void Run() = 0;

 private:
  static void *RunWrapper(void *);

  pthread_t thread;
};

#endif
Run Code Online (Sandbox Code Playgroud)

实施

#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);
}
Run Code Online (Sandbox Code Playgroud)

而实际上试图做某事的文件

#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;
}
Run Code Online (Sandbox Code Playgroud)

我在过去10小时内遇到的错误是:

pure virtual method called
terminate called without an active exception
Run Code Online (Sandbox Code Playgroud)

Chr*_*odd 5

问题是main函数返回时,main中的MyThread对象会被销毁,这可能发生在新线程实际调用其Start方法之前.

作为销毁过程的一部分,在调用基类析构函数之前,vtable将被重置为基类的vtable,因此当稍后RunWrapper调用运行时,它最终会触发纯虚方法错误.在被破坏的对象上调用方法会导致未定义的行为,因此可能会发生任何事情; 这种行为是C++编译器如何实现析构函数和堆栈分配的意外.