首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >C++继承:当虚拟方法被重写时调用它

C++继承:当虚拟方法被重写时调用它
EN

Stack Overflow用户
提问于 2015-07-17 23:24:24
回答 1查看 1K关注 0票数 7

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

代码语言:javascript
复制
#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()函数中被调用。

代码语言:javascript
复制
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类中被重写。更糟糕的是,它有时运行正常?

代码语言:javascript
复制
$ ./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

这里有什么问题吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-07-17 23:30:55

一步一步地走:

1)构造对象。

2)执行以下代码:

代码语言:javascript
复制
if (started_.load() == false) {
  started_ = true;
  thread_ = std::thread([&] () {
    run();
  });
}

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

这是你的窃听器:

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

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

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

未定义的行为。

你每隔一段时间就会碰到这样的断言,这可能是这种未定义行为的结果之一。

票数 10
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/31486128

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档