c++ - 在基类/派生类中调用 C++ 的纯虚函数

标签 c++ multithreading

我有这个基类:

class Base {
public:
  Base();
  virtual ~Base();
protected:
  virtual on_next_item(std::string& item) = 0;
private:
    void read_loop();
};

和这个派生类:

class Derived : public Base {
public:
  Derived();
  virtual ~Derived();
protected:
  void on_next_item(std::string& item) override;
};

Base 类构造函数中,我启动了一个线程,该线程从套接字读取数据并调用在派生类上调用的 on_next_item()。 在 Base 析构函数中,读取器线程通过原子标志停止。 但有时 read_loop 仍然会调用 on_next_item 并且我得到一个“调用纯虚函数!”错误。我假设我在比赛条件下运行:

子类(对象)已经被析构,函数不再注册。

有没有合适的方法来解决这个竞争条件?

为了完整起见,这里是阅读器循环:

while (running.load())
{
  string item = read();
  if (running.load())
  {
    on_text_item(item);
  }
}

运行标志在 Base 类析构函数中切换为 false。

编辑(完整的运行示例,必须执行多次才能在问题中运行):

#include <atomic>
#include <boost/thread/thread.hpp>
#include <boost/chrono.hpp>
#include <iostream>

class Base
{
public:
  Base() : running(true)
  {
    readerThread = new boost::thread(&Base::read_loop, this);
  }

  virtual ~Base()
  {
    running = false;

    delete readerThread;
    readerThread = nullptr;
  }

protected:
  virtual void on_next_item(std::string &item) = 0;

private:
  boost::thread *readerThread;

  void read_loop()
  {
    std::string element = "Element";
    while (running.load())
    {
      boost::this_thread::sleep_for(boost::chrono::milliseconds(2));
      on_next_item(element);
    }
  }

  std::atomic_bool running;
};

class Derived : public Base
{
public:
  Derived() : Base()
  {
  }

  virtual ~Derived()
  {
  }

protected:
  virtual void on_next_item(std::string &item)
  {
    std::cout << "On Next Item " << item << std::endl;
  }
};

void constAndDestruct()
{
  Derived d;
  boost::this_thread::sleep_for(boost::chrono::seconds(2));
}

int main(int argc, char **argv)
{

  constAndDestruct();
  boost::this_thread::sleep_for(boost::chrono::seconds(2));
}

谢谢!

最佳答案

从构造函数或析构函数调用虚函数是 generally considered a bad idea .函数调用实际上将像函数不是虚拟的一样完成,因为此时 Derived 的构造函数尚未被调用,成员变量或 Derived 仍未初始化。 ..

显而易见的解决方案是将类的逻辑移至公共(public)成员函数并在创建对象后立即调用该函数:

Derived d;
d.run();

关于c++ - 在基类/派生类中调用 C++ 的纯虚函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45729152/

相关文章:

c++ - "enumeral and non-enumeral type in conditional expression"背后的推理

C++ 应用程序 : clear commandline arguments?

java - 如何写入/读取已锁定的文件?

c# - 最多有 N 个线程按 FIFO 顺序执行的代码部分

c# - 运行多个 UI 线程

具有意外 cpu 消耗的 C 多线程进程

python - 用于在 python 中预加载文件的线程缓冲区迭代器

c++ - Linux 上良好的文本文件 IO C/C++ 指南

c++ - 如何将 priority_queue 与类实例的非静态比较方法一起使用?

c++ - 如何销毁和重建 lua_State