我有类A和A对象列表。 A有一个函数f,应该每X秒执行一次(对于第一个实例每1秒,对于秒每5秒等等)。 我有一个调度程序类负责在正确的时间执行功能。 我想要做的是创建一个新类,ATime,它将ptr保存到一个实例,并且时间A :: f应该被执行。调度程序将保留Atime的最小优先级队列。嵌套类或不嵌套类?
- 您认为这是正确的实施?
- ATime应该是调度程序的嵌套类吗?
我有类A和A对象列表。 A有一个函数f,应该每X秒执行一次(对于第一个实例每1秒,对于秒每5秒等等)。 我有一个调度程序类负责在正确的时间执行功能。 我想要做的是创建一个新类,ATime,它将ptr保存到一个实例,并且时间A :: f应该被执行。调度程序将保留Atime的最小优先级队列。嵌套类或不嵌套类?
从你的描述,听起来像它可以工作:-)
恕我直言类ATime
属于调度多到A.这是必要的调度,以完成其工作,这是不实际上,A(和世界其他地方)甚至不需要知道它的存在 - 所以把它放在调度器的私有嵌套类中对我来说是适合的。
这种类最好是嵌套在您的调度程序类中的私有结构,因此您可以轻松访问调度程序类中的所有字段。 (默认情况下,结构的所有字段都是公共的)。
至于第二部分(以及标题中的问题),IMO完全是一个品味问题。您也可以选择减少Scheduler类定义中的混乱,并将ATime放置在带有警告名称(如detail
)的子名称空间中,以防止人们使用它。毕竟,如果它只对调度程序有用,没有太多需要将其隐藏太多 - 无论如何,没有人会想要使用它。可能它在C++ 0x中可能有所不同(我想我已经听说过一些传闻,它将如何改变嵌套类和父类之间的可访问性规则,在这种情况下嵌套可能更有价值)。
对于通用性,您可能还想使用模板,也许最后是Scheduler<A>
(使用TimedOperation<A>
)(或无数个可能的改进/推广)?
这可能是有点太先进,但在这里不用...
boost::function和boost::bind可用于实现并不需要知道A类东西这将使您的调度更通用的调度并可重复使用。
下面是说明如何这些升压设备可以在你的情况下,可以使用的一些示例代码:
#include <ctime>
#include <queue>
#include <boost/function.hpp>
#include <boost/bind.hpp>
struct Foo
{
void onScheduler(time_t time) {/*...*/}
};
struct Bar
{
void onScheduler(time_t time) {/*...*/}
};
typedef boost::function<void (time_t)> SchedulerHandler;
struct SchedulerEvent
{
bool operator<(const SchedulerEvent& rhs) const {return when < rhs.when;}
SchedulerHandler handler;
time_t when;
};
class Scheduler
{
public:
void schedule(SchedulerHandler handler, time_t when)
{
SchedulerEvent event = {handler, when};
queue_.push(event);
}
private:
std::priority_queue<SchedulerEvent> queue_;
void onNextEvent()
{
const SchedulerEvent& next = queue_.top();
next.handler(next.when);
queue_.pop();
}
};
int main()
{
Scheduler s;
Foo f1, f2;
Bar b1, b2;
time_t now = time(0);
s.schedule(boost::bind(&Foo::onScheduler, &f1, _1), now + 1);
s.schedule(boost::bind(&Foo::onScheduler, &f2, _1), now + 2);
s.schedule(boost::bind(&Bar::onScheduler, &b1, _1), now + 3);
s.schedule(boost::bind(&Bar::onScheduler, &b2, _1), now + 4);
// Do scheduling...
return 0;
}
注意Scheduler
一无所知Foo
& Bar
,反之亦然。所有Scheduler
真的想要的是一个“回调”仿函数,匹配SchedulerHandler
指定的签名。
如果您需要取消SchedulerEvent
,则事情会变得有点复杂,因为boost::function
对象不具有可比性。为了解决这个问题,您需要在注册事件时返回某种“连接”标记。这实际上就是Boost.Signal所做的。
希望这会有所帮助。