c++继承:当虚方法被重写时调用它

C++ Inheritance : Calling virtual method when it has been overridden

本文关键字:重写 调用 方法 继承 c++      更新时间:2023-10-16

我试图建立一个service对象,可以运行(即执行它的run()函数)在一个单独的线程。这是服务对象

#include <boost/noncopyable.hpp>
#include <atomic>
#include <thread>
#include <iostream>
class service : public boost::noncopyable {
 public:
  service() : stop_(false), started_(false) { }
  virtual ~service() {
    stop();
    if (thread_.joinable()) {
      thread_.join();
    }
  }
  virtual void stop() { stop_ = true; }
  virtual void start() {
    if (started_.load() == false) {
      started_ = true;
      thread_ = std::thread([&] () {
        run();
      });
    }
  }
 protected:
  virtual void run() = 0;
  std::atomic<bool> stop_;
  std::atomic<bool> started_;
  std::thread thread_;
};

我正在创建一个test类,它继承了这个抽象类,并在main()函数中调用

class test : public service {
 public:
  test() : service() {
    std::cout<< "CTOR" << std::endl;
    start();
  }
  ~test() {
    std::cout<< "DTOR" << std::endl;
  }
 protected:
  void run() override {
    std::cout << "HELLO WORLD" <<std::endl;
  }
};

int main() {
  test test1;
  return 0;
}

现在当我执行这个,为什么我得到一个错误说pure virtual function called ?run()函数显然在test类中被重写了。更糟糕的是,它有时运行正确?

$ ./a.out
CTOR
DTOR
pure virtual method called
terminate called without an active exception
$ ./a.out
CTOR
DTOR
pure virtual method called
terminate called without an active exception
$ ./a.out
CTOR
DTOR
pure virtual method called
terminate called without an active exception
$ ./a.out
CTOR
DTOR
HELLO WORLD
$ ./a.out
CTOR
DTOR
pure virtual method called
terminate called without an active exception

这里可能出了什么问题?

跟着做,一步一步来:

1)你构造对象。

2)执行以下代码:
if (started_.load() == false) {
  started_ = true;
  thread_ = std::thread([&] () {
    run();
  });
}

父线程立即返回main(),在那里它立即退出并销毁你的对象。

这是你的bug:

  • 您不能保证在父线程终止进程之前,在start()中启动的线程将到达对run()的调用。子线程和父线程同时运行。

所以,每隔一段时间,父线程会在子线程启动之前销毁对象,并调用run()。

此时,调用run()方法的对象已经被销毁。

未定义的行为。

每隔一段时间,你正在点击的断言是这种未定义行为的一个可能结果。