如何实现一个简单的事件队列
How to implement a simple event queue?
所以,我首先在谷歌上搜索了大量内容,但所有的解决方案似乎都非常复杂。所以,我想我会问这里,看看这项任务是否真的需要我遇到的那种方法。。。
所以,假设我有一个Event
类。我希望它有一个time
变量和一个functionToExecuteAtTime
函数指针/变量/魔术代码,可以将任何旧函数传递给这个类。
此外,我希望将事件保存在一个优先级队列中,该队列按时间顺序排列事件并执行它们"承载"的功能。但是暂时忘记这一点
像这样的。。。
class Agent
{
public:
int id;
float cash;
Agent::Agent
{
cash = 100;
}
}
class uberSystem
{
public:
float assets;
int supplyOfDeadlyPoison;
float poisonCost;
std::vector<Agent> agents;
uberSystem::uberSystem
{
assets = 100000;
supplyOfDeadlyPoison = 100000;
poisonCost = 8;
for(int i = 0; i < 100; i++)
{
Agent newAgent;
newAgent.id = i;
agents.push_back(newAgent)
}
}
};
class Event
{
public:
int time;
SOMETHING_THAT_LETS_ME_HOLD_FUNCTIONS myFunction;
Event::Event(int t, SOMETHING_THAT_LETS_ME_HOLD_FUNCTIONS func)
{
time = t;
myFunction = func;
}
}
int uselessFunction()
{
return 42;
}
void buyPoisonAndKillAgent(Agent &myAgent, uberSystem &mySystem)//obviously not good...
{
myAgent.cash -= mySystem.poisonCost;
mySystem.assets += mySystem.poisonCost;
mySystem.agents.erase(mySystem.agents.begin()+myAgent.id);
mySystem.supplyOfDeadlyPoison -= 1;
}
int main()
{
uberSystem newSystem;
// Event newEvent(100, uselessFunction());//make a new event
Event newEvent(100, buyPoisonAndKillAgent(newSystem.agents[5], newSystem));
newEvent.myFunction;//run the bloody function
return 0;
}
好吧,现在我打字的时候,这看起来像是一厢情愿的想法。那么,我该如何实现呢?函数指针是可行的吗?还是有什么更好的方法我还没找到?
哦,显然我确实有std::function
可用。。。我一直都不在石器时代!
谢谢!
您可以有一个基类事件(由@EdHeal提出),然后有一个模板子类存储您的函数指针:
class Event {
public:
int time;
Event(int t) : time(t) {}
virtual ~Event(){}
virtual void myFunction() = 0;
};
template<typename TFunc>
class TEvent : public Event {
public:
TFunc func;
TEvent(int t, TFunc f) : Event(t), func(f) {}
void myFunction() { func(); }
};
template<typename TFunc>
auto_ptr<Event> make_event(int time, TFunc func) {
return std::auto_ptr<Event>(new TEvent<TFunc>(time,func));
}
使用辅助函数make_event
,可以很容易地调用并自动推导类型:
void useless() {std::cout << "Func A";}
struct functor {
void operator()() {std::cout << "Functor B";}
};
struct paramFunctor {
paramFunctor(int x, double y): result(0), m_x(x), m_y(y){}
void operator()() {
std::cout << "Params: x:" << m_x << ", y:" << m_y << "n";
}
long long result;
private:
int m_x;
double m_y;
};
int main() {
auto_ptr<Event> e1 = make_event(10,useless);
auto_ptr<Event> e2 = make_event(100,functor());
auto_ptr<Event> e2 = make_event(100,paramFunctor(1,2.0));
// your code goes here
e1->myFunction();
e2->myFunction();
e3->myFunction();
return 0;
}
当然,如果可以访问C++11(或TR1,或boost),则根本不需要所有这些(正如其他答案所描述的)
为什么不做这个
class Event {
private:
int time;
public:
Event(int t) : time(t) { }
virtual void DoEvent() = 0;
};
class MyEVent: public Event {
public:
MyEvent(int t) : Event(t) { }
void DoEvent() { std::cout << "Event called" << std::endl;
};
然后
int main() {
MyEvent e(100);
e.DoEvent();
return 0;
}
这看起来更简单,您可以奢侈地添加事件所需的任何数据。
对于列表,您使用Event
指针,例如Event *e = new MyEvent(100)
保存泛型函数或闭包的最简单方法是使用std::function
;在没有C++11的情况下,boost::function
是一个很好的占位符
这产生:
class Event {
public:
private:
std::time_t time;
boost::function<void()> function;
}; // class Event
注意,函数的签名需要精确:void()
是一个不带参数、不返回任何内容的函数。
此外,请注意,您可以任意谓词、函子类或lambda,只要其中一个operator()
与预期签名匹配即可。
相关文章:
- 在c++中用vector填充一个简单的动态数组
- 如何使用 samtools C API 构建一个简单的主.cpp文件
- 为什么一个简单的程序不能立即启动
- C++ - 在我尝试制作一个简单的计算器时有一个"uninitialized local variable y used"警告
- 为什么 MSVC C++编译器将一个简单的 Hello World 扩展为 4000 行汇编?
- 我写了一个简单的矢量程序,在其中我得到了以下输出。你能帮我理解它的输出吗?
- 如何使用 c++ 在命令行中创建一个简单的字符控制器?
- 对于 ~95% 写入/5% 读取线程安全的无序列图,有没有一个简单的解决方案?
- 在C++中创建一个简单的数据包路由器,如何跟踪"客户端"?
- 创建一个简单的前向迭代器,该迭代器在循环缓冲区的"end"处自动换行
- 我已经安装了用于c++编程的升华3,但在编写了一个简单的程序后,我遇到了以下错误
- 如何设置一个简单的CGAL+Qt程序
- 如何在一个简单的C++项目中使用Poco库
- 我创建了一个简单的程序,但有些地方不对劲
- Qt的新信号/时隙语法问题 - 连接到一个简单的函数
- 一个简单的 win32 多线程代码.这能行吗?
- 我正在尝试构建一个简单的程序来从 mysql 数据库中读取信息
- 创建一个简单的计算器,添加时遇到问题
- 我正在编写一个简单的客户端套接字应用程序,但在连接后服务器收到一个空缓冲区
- 为什么一个简单的"Hello World"风格的程序不能用Turbo C++编译?