我有这个基类:
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));
}谢谢!
发布于 2017-08-17 15:47:58
从构造函数或析构函数调用虚函数是generally considered a bad idea。函数调用实际上就像函数不是虚拟的一样,因为在这一点上,Derived的构造函数还没有被调用,成员变量或Derived仍然没有初始化……
显而易见的解决方案是将类的逻辑移动到公共成员函数,并在对象创建后立即调用该函数:
Derived d;
d.run();发布于 2017-08-17 23:50:07
我建议做出以下改变:
on_next_item(element);}
https://stackoverflow.com/questions/45729152
复制相似问题