嵌套类还是非嵌套类?

发布于 2024-08-24 20:28:13 字数 242 浏览 5 评论 0原文

我有 A 类和 A 对象列表。 A 有一个函数 f 应该每 X 秒执行一次(第一个实例每 1 秒执行一次,第二个实例每 5 秒执行一次,等等)。 我有一个调度程序类,负责在正确的时间执行函数。 我想做的是创建一个新类 ATime,它将保存 A 实例的 ptr 以及应该执行 A::f 的时间。调度程序将保存一个 Atime 的最小优先级队列。

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

I have class A and list of A objects. A has a function f that should be executed every X seconds (for the first instance every 1 second, for the seconds instance every 5 seconds, etc.).
I have a scheduler class that is responsible to execute the functions at the correct time.
What i thought to do is to create a new class, ATime, that will hold ptr to A instance and the time A::f should be executed. The scheduler will hold a min priority queue of Atime.

  1. Do you think it is the correct implementation?
  2. Should ATime be a nested class of the scheduler?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

找个人就嫁了吧 2024-08-31 20:28:13

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

IMHO 类 ATime 属于调度程序而不是 A。调度程序有必要完成其工作,而 A 不需要它事实上,A(以及世界的其他部分)甚至不需要知道它的存在 - 因此将它放在调度程序的私有嵌套类中对我来说是合适的。

From what you describe, sounds like it could work :-)

IMHO class ATime belongs to the scheduler more than to A. It is necessary for the scheduler to do its job, and it is not needed for A. In fact, A (and the rest of the world) need not even know about its existence - so putting it a private nested class of the scheduler would be appropriate for me.

梦忆晨望 2024-08-31 20:28:13

这可能有点太先进了,但是这里...

boost::functionboost::bind< /a> 可用于实现不需要了解 A 类任何信息的调度程序。这将使您的调度程序更加通用和可重用。

下面是一些示例代码,说明了如何在您的案例中使用这些 Boost 工具:

#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;
}

请注意,SchedulerFooFoo 一无所知。 Bar,反之亦然。 Scheduler 真正想要的是一个与 SchedulerHandler 指定的签名相匹配的“回调”函子。

如果您需要可取消的 SchedulerEvent ,事情会变得有点复杂,因为 boost::function 对象不具有可比性。为了解决这个问题,您需要在注册事件时返回某种“连接”令牌。这本质上就是 Boost.Signal 所做的事情。

希望这有帮助。

This may be a little too advanced, but here goes...

boost::function and boost::bind can be used to implement a scheduler that does not need to know anything about class A. This would make your scheduler more generic and reusable.

Here is some sample code that illustrates how those Boost facilities can be used in your case:

#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;
}

Note that Scheduler knows nothing about Foo & Bar, and vice-versa. All Scheduler really wants is a "callback" functor that matches the signature specified by SchedulerHandler.

If you need a SchedulerEvent to be cancellable, things get a bit complicated because boost::function objects are not comparable. To get around this, you'll need to return some kind of "connection" token when registering events. This is essentially what Boost.Signal does.

Hope this helps.

晚雾 2024-08-31 20:28:13

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

This sort of class is best made a private struct nested within your scheduler class, so you can easily access all fields inside the scheduler class. (All fields of a struct are public by default.)

挽手叙旧 2024-08-31 20:28:13

至于第二部分(以及标题中的问题),IMO,这完全是一个品味问题。您也可以选择减少 Scheduler 类定义中的混乱,并将 ATime 放置在带有警告名称(如 detail)的子命名空间中,以防止人们使用它。毕竟,如果它仅对调度程序有用,则没有必要将其隐藏得太多 - 无论如何都没有人愿意使用它。

也许在 C++0x 中可能会有所不同(我想我听说过一些传言它将如何改变嵌套类和父类之间的可访问性规则,或者这样,在这种情况下嵌套可能更值得)。

为了通用性,您可能还想使用模板,并且可能最终得到 Scheduler (使用 TimedOperation)(或无数潜在的改进) /概括)?

As to the second part (and the question in the title), IMO it is completely a matter of taste. You could just as well choose to reduce the clutter in the definition of the Scheduler class, and place ATime in a subnamespace with a warning name (like detail) to keep people from using it. After all, if it is only useful for the Scheduler, there's not much need to hide it too much - nobody's going to want to use it anyway.

Perhaps it might be different in C++0x (I think I've heard some rumours how it's going to change the accessibility rules between nested and parent class, or so, in which case nesting might be more worthwhile).

For genericity you might also want to make use of templates, and perhaps end up with Scheduler<A> (using a TimedOperation<A>) (or a myriad of potential refinements/generalizations of that)?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文