C++11 线程不能与虚拟成员函数一起使用

2024-01-04

我试图让一个类运行一个线程,它将在循环中调用一个名为 Tick() 的虚拟成员函数。然后我尝试派生一个类并重写 base::Tick()。

但在执行时,程序只是调用基类的 Tick 而不是覆盖它。有什么解决办法吗?

#include <iostream>
#include <atomic>
#include <thread>
#include <chrono>

using namespace std;

class Runnable {
 public:
  Runnable() : running_(ATOMIC_VAR_INIT(false)) {

   }
  ~Runnable() { 
    if (running_)
      thread_.join();
  }
  void Stop() { 
    if (std::atomic_exchange(&running_, false))
      thread_.join();
  }
  void Start() {
    if (!std::atomic_exchange(&running_, true)) {
      thread_ = std::thread(&Runnable::Thread, this);
    }
  }
  virtual void Tick() {
    cout << "parent" << endl;
  };
  std::atomic<bool> running_;

 private:
  std::thread thread_;
  static void Thread(Runnable *self) {
    while(self->running_) {
      self->Tick();
      std::this_thread::sleep_for(std::chrono::milliseconds(100));
    }
  }
};

class Fn : public Runnable {
 public:
  void Tick() {
    cout << "children" << endl;
  }
};

int main (int argc, char const* argv[])
{
  Fn fn;
  fn.Start();
  return 0;
}

outputs:

parent

在使用完对象之前,不能让其超出范围!这return 0;在......的最后main causes fn超出范围。所以当你抽出时间打电话的时候tick,无法保证该对象甚至不再存在。

(其中的逻辑~Runnable完全坏了。在析构函数内部已经太晚了——对象已经至少部分被破坏了。)

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C++11 线程不能与虚拟成员函数一起使用 的相关文章

随机推荐