首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何避免在派生类中先发制人?

如何避免在派生类中先发制人?
EN

Stack Overflow用户
提问于 2022-06-22 08:30:52
回答 1查看 77关注 0票数 3

我启动了一个基于线程的线程。在这个线程中调用了一个纯虚拟函数。我在派生类中实现它。

代码语言:javascript
复制
#include <iostream>
#include <memory>
#include <thread>
struct Base {
  std::unique_ptr<std::thread> th;
  virtual void foo() = 0;
  void bar() { 
    th = std::make_unique<std::thread>(
      [this](){
        foo();
      }
    );
  }
  virtual ~Base(){
    th->join();
  }
};

struct Derived : public Base {
  virtual void foo() override {
    std::cout << "impl in derived" << std::endl;
  }
};
int main() {
  Derived d;
  d.bar();
  return 0;
}

然而,在这些代码中,派生对象将在基对象之前解构。

代码语言:javascript
复制
pure virtual method called
terminate called without an active exception
Aborted (core dumped)

在这种情况下,如何控制破坏秩序?

EN

回答 1

Stack Overflow用户

发布于 2022-06-22 09:00:50

这是一个并发问题,所发生的是未定义的行为。如果您构建了不同的配置(例如,从Debug切换到发布版),应用程序就会以不同的方式中断是完全可能的。

具体来说,我认为当main完成执行并超出范围时,您的线程才刚刚开始。这将调用所有的析构,最终(在您的实现中),foo指向基类实现(在派生析构函数的末尾),然后main在基析构函数中被阻塞--在调用join。

如何修复:

在一个单独的函数中移动联接并显式调用它:

代码语言:javascript
复制
struct Base {
  std::unique_ptr<std::thread> th;
  virtual void foo() = 0;
  void bar() { 
    th = std::make_unique<std::thread>(
      [this](){
        foo();
      }
    );
  }
  virtual ~Base() = default;

  void join() { th->join(); }
};

int main() {
  Derived d;
  d.bar();
  d.join(); // prevent the destruction of the derived part
            // and main blocking before completing the base
            // destructor execution.
  return 0;
}
票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/72712133

复制
相关文章

相似问题

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