Frage

Ich habe Klasse A und Liste der Objekte.A hat eine Funktion f, die ausgeführt werden soll, wird alle X Sekunden (für die erste Instanz jedes 1 zweite, für den Sekunden-Instanz alle 5 Sekunden, etc.).Ich habe einen scheduler-Klasse verantwortlich ist, zum ausführen der Funktionen, die zur richtigen Zeit.Was ich dachte zu tun ist erstellen Sie eine neue Klasse, ATime, dass wird halten ptr zu Einer Instanz und die Zeit A::f ausgeführt werden soll.Der scheduler wird halten Sie einen min-priority-queue-Atime.

  1. Tun Sie denken, es ist die korrekte Umsetzung?
  2. Sollte ATime eine geschachtelte Klasse der scheduler?
War es hilfreich?

Lösung

Von dem, was Sie beschreiben, klingt wie es funktionieren könnte: -)

IMHO Klasse ATime gehört zu den Scheduler mehr als A. Es ist notwendig, dass der Scheduler seine Arbeit zu tun, und es ist nicht für A. benötigt In der Tat, A (und der Rest der Welt) muss nicht einmal wissen, über seine Existenz - legt es so eine private verschachtelte Klasse des Schedulers für mich angemessen wäre,

.

Andere Tipps

Dies kann ein wenig zu weit fortgeschritten, aber hier geht ...

boost :: function und boost :: bind kann einen Scheduler zu implementieren verwendet werden, braucht nichts über Klasse A. wissen Dies würde Ihre Scheduler allgemeinere und wiederverwendbar machen.

Hier finden Sie einige Beispielcode, der veranschaulicht, wie diese Boost-Einrichtungen können in Ihrem Fall verwendet werden:

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

Beachten Sie, dass Scheduler weiß nichts über Foo & Bar, und umgekehrt. Alle Scheduler wirklich will, ist ein „Rückruf“ Funktor, der die Unterschrift von SchedulerHandler angegebenen übereinstimmt.

Wenn Sie eine SchedulerEvent brauchen kündbar zu sein, werden die Dinge ein wenig kompliziert, weil boost::function Objekte nicht vergleichbar sind. Um dies zu umgehen, müssen Sie eine Art „Verbindung“ zurückzukehren Token bei der Anmeldung Ereignisse. Dies ist im Wesentlichen, was Boost.Signal der Fall ist.

Hope, das hilft.

Diese Art von Klasse ist am besten eine private Struktur in Ihrer Scheduler Klasse verschachtelt gemacht, so dass Sie leicht alle Felder innerhalb der Ablaufsteuerungs-Klasse zugreifen können. (Alle Felder einer Struktur öffentlich sind standardmäßig aktiviert.)

Als der zweite Teil (und die Frage im Titel), IMO es ist ganz eine Frage des Geschmacks.Sie könnte genauso gut wählen, reduzieren Sie die Unordnung in der definition der Scheduler-Klasse, Ort und Zeit, in ein unternamespace mit einer Warnung Namen (wie detail), Menschen daran zu hindern, es zu verwenden.Nach alle, wenn es nur nützlich für den Scheduler, gibt es nicht viel braucht, um zu verbergen, dass es zu viel - niemand ist gehen zu wollen, es trotzdem zu benutzen.

Vielleicht könnte es anders sein, in C++0x (ich glaube, ich habe gehört, einige Gerüchte, wie es geht ändern Sie die Regeln, die den Zugang zwischen den verschachtelten und übergeordneten Klasse oder so, in dem Fall nesting möglicherweise mehr lohnt).

Für genericity vielleicht wollen Sie auch Gebrauch machen von Vorlagen, und vielleicht am Ende mit Scheduler<A> (mit einem TimedOperation<A>) (oder eine Vielzahl von möglichen Verbesserungen/Verallgemeinerungen dass)?

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top