Pregunta

Tengo la clase A y A lista de objetos. A tiene una función f que se debe ejecutar cada X segundos (para el primer ejemplo, cada 1 segundo, para la instancia segundos cada 5 segundos, etc.). Tengo una clase de planificación que se encarga de ejecutar las funciones en el momento correcto. Lo que pensé que hacer es crear una nueva clase, ATIME, que llevará a cabo ptr a una instancia y el tiempo de A :: f debe ser ejecutado. El planificador llevará a cabo una cola de prioridad min de Atime.

  1. ¿Usted cree que es la correcta implementación?
  2. debería ser ATIME una clase anidada del programador?
¿Fue útil?

Solución

A partir de lo que usted describe, suena como que podría funcionar: -)

ATime clase en mi humilde opinión pertenece al programador más a A. Es necesario que el programador haga su trabajo, y no es necesaria para A. De hecho, A (y el resto del mundo) ni siquiera necesitan saber acerca de su existencia - por lo que poner una clase anidada privada del planificador sería apropiado para mí

.

Otros consejos

Esto puede ser un poco demasiado avanzado, pero aquí va ...

impulso :: función y impulso :: unen se puede utilizar para implementar un planificador que no necesita saber nada acerca de la clase A. Esto haría que el planificador más genérico y reutilizable.

Aquí hay un código de ejemplo que ilustra cómo esas instalaciones Boost se pueden utilizar en su caso:

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

Tenga en cuenta que Scheduler no sabe nada sobre Foo y Bar, y viceversa. Todo Scheduler realmente quiere es un funtor "devolución de llamada" que coincide con la firma especificada por SchedulerHandler.

Si necesita un SchedulerEvent ser canceladas, las cosas se ponen un poco complicado ya que los objetos boost::function no son comparables. Para evitar esto, tendrá que volver a algún tipo de token "conexión" al registrar eventos. Esto es esencialmente lo que hace Boost.Signal.

Espero que esto ayude.

Este tipo de clase se hace mejor una estructura privada anidada dentro de la clase de programador, por lo que se puede acceder fácilmente a todos los campos dentro de la clase planificador. (Todos los campos de una estructura son públicos por defecto.)

En cuanto a la segunda parte (y la pregunta en el título), la OMI es totalmente una cuestión de gusto. Se podía así optar por reducir el desorden en la definición de la clase Scheduler, y colocar en un ATIME subespaciodenombres con un nombre de alerta (como detail) para mantener a la gente de su uso. Después de todo, si sólo es útil para el programador, no hay mucha necesidad de ocultarlo demasiado -. Nadie va a querer utilizar de todos modos

Tal vez podría ser diferente en C ++ 0x (creo que he oído algunos rumores de cómo va a cambiar las reglas de accesibilidad entre anidada y los padres de clase, más o menos, en cuyo caso la anidación podría ser más útil).

Para genericity también puede ser que desee hacer uso de plantillas, y tal vez terminar con Scheduler<A> (utilizando un TimedOperation<A>) (o una miríada de posibles refinamientos / generalizaciones de eso)?

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top