2010-03-13 107 views
3

我有类A和A对象列表。 A有一个函数f,应该每X秒执行一次(对于第一个实例每1秒,对于秒每5秒等等)。 我有一个调度程序类负责在正确的时间执行功能。 我想要做的是创建一个新类,ATime,它将ptr保存到一个实例,并且时间A :: f应该被执行。调度程序将保留Atime的最小优先级队列。嵌套类或不嵌套类?

  1. 您认为这是正确的实施?
  2. ATime应该是调度程序的嵌套类吗?

回答

4

从你的描述,听起来像它可以工作:-)

恕我直言类ATime属于调度多到A.这是必要的调度,以完成其工作,这是不实际上,A(和世界其他地方)甚至不需要知道它的存在 - 所以把它放在调度器的私有嵌套类中对我来说是适合的。

0

这种类最好是嵌套在您的调度程序类中的私有结构,因此您可以轻松访问调度程序类中的所有字段。 (默认情况下,结构的所有字段都是公共的)。

0

至于第二部分(以及标题中的问题),IMO完全是一个品味问题。您也可以选择减少Scheduler类定义中的混乱,并将ATime放置在带有警告名称(如detail)的子名称空间中,以防止人们使用它。毕竟,如果它只对调度程序有用,没有太多需要将其隐藏太多 - 无论如何,没有人会想要使用它。可能它在C++ 0x中可能有所不同(我想我已经听说过一些传闻,它将如何改变嵌套类和父类之间的可访问性规则,在这种情况下嵌套可能更有价值)。

对于通用性,您可能还想使用模板,也许最后是Scheduler<A>(使用TimedOperation<A>)(或无数个可能的改进/推广)?

1

这可能是有点太先进,但在这里不用...

boost::functionboost::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所做的。

希望这会有所帮助。