【发布时间】:2014-01-03 16:27:24
【问题描述】:
我正在尝试用 C++ 编写事件驱动的模拟。现在它只是一个unique_ptrs 到基本Event 类的基本优先级队列:
class Event
{
public:
double time;
Event(double time);
virtual void handle() = 0;
};
struct EventCompare
{
bool operator()(std::unique_ptr<Event> e1, std::unique_ptr<Event> e2) {
return e1->time > e2->time;
}
};
class DumpSimulationEvent : public Event
{
public:
DumpSimulationEvent(const double time);
void handle();
};
typedef std::priority_queue<std::unique_ptr<Event>, std::vector<std::unique_ptr<Event>>, EventCompare> EventQueue;
class Simulation
{
double time;
EventQueue eventQueue;
public:
Simulation();
void run();
};
Event::Event(const double t)
{
time = t;
}
DumpSimulationEvent::DumpSimulationEvent(const double t) : Event(t)
{
}
void DumpSimulationEvent::handle()
{
std::cout << "Event time: " << time;
}
Simulation::Simulation()
{
time = 0;
eventQueue = EventQueue();
std::unique_ptr<DumpSimulationEvent> dumpEvent5(new DumpSimulationEvent(5));
//eventQueue.emplace(dumpEvent5);
}
void Simulation::run()
{
while (!eventQueue.empty()) {
std::unique_ptr<Event> currentEvent = std::move(eventQueue.top());
//eventQueue.pop();
time += currentEvent->time;
currentEvent->handle();
}
}
Main 函数(上面未显示)只是创建一个 Simulation 实例并调用 run() 方法。问题是取消注释 emplace() 或 pop() 会导致
error C2280: 'std::unique_ptr<Event,std::default_delete<_Ty>>::unique_ptr(const std::unique_ptr<_Ty,std::default_delete<_Ty>> &)' : attempting to reference a deleted function c:\program files (x86)\microsoft visual studio 12.0\vc\include\xutility 521 1
研究表明,最可能的原因是试图复制 unique_ptr。然而,我不知道它是否是真正的原因,它是否真的发生在注释行或只是在那里变得可见。将 std::move 添加到 emplace 参数似乎没有帮助。
【问题讨论】:
-
std::move(eventQueue.top());这将失败,因为priority_queue仅提供对top的常量访问。见stackoverflow.com/q/20149471/420683 -
不是您看到的错误的原因,而是
Event类应该有一个virtual析构函数,否则它是 UB 将DumpSimulationEvent对象粘贴到unique_ptr<Event>中 -
定义虚拟析构函数是否意味着我必须显式定义析构函数并为派生类移动构造函数?
标签: c++ c++11 unique-ptr