Pergunta

Eu tenho classe A e lista de objetos a. A tem uma função f que deve ser executada a cada X segundos (por exemplo, o primeiro a cada 1 segundo, para o segundo exemplo a cada 5 segundos, etc.). Eu tenho uma classe programador que é responsável por executar as funções no tempo correto. O que eu pensei a fazer é criar uma nova classe, ATIME, que irá realizar ptr a uma instância eo tempo A :: f deve ser executado. O programador irá realizar uma fila min prioridade do atime.

  1. Você acha que é a implementação correta?
  2. deve ATIME ser uma classe aninhada do programador?
Foi útil?

Solução

Do que você descreve, soa como ele poderia funcionar: -)

IMHO classe ATime pertence ao programador mais do que para A. É necessário que o programador para fazer o seu trabalho, e isso não é necessário para A. Na verdade, A (eo resto do mundo) nem precisam saber sobre sua existência - para colocá-lo uma classe aninhada privada do programador seria apropriado para mim

.

Outras dicas

Isto pode ser um pouco avançado, mas aqui vai ...

boost :: função e boost :: bind pode ser usado para implementar um programador que não precisa saber nada sobre a classe A. Isto faria com que o seu programador mais genérico e reutilizável.

Aqui está um código de exemplo que ilustra como as instalações do impulso pode ser usado em seu 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;
}

Note que Scheduler nada sobre Foo & Bar, e vice-versa sabe. Todos Scheduler realmente quer é um functor "callback" que corresponda a assinatura especificado pelo SchedulerHandler.

Se você precisa de um SchedulerEvent ser canceladas, as coisas ficam um pouco complicado porque os objetos boost::function não são comparáveis. Para contornar este problema, você precisa de retornar algum tipo de "conexão" token ao registrar eventos. Este é essencialmente o que Boost.Signal faz.

Espero que isso ajude.

Este tipo de classe de melhor se faz uma estrutura privada aninhada dentro de sua classe scheduler, para que você possa acessar facilmente todas as áreas dentro da classe programador. (Todos os campos de um struct são públicos por padrão).

Quanto à segunda parte (e a pergunta no título), IMO, é completamente uma questão de gosto. Você poderia muito bem optar por reduzir a desordem na definição da classe Scheduler, e lugar ATIME em um subnamespace com um nome de alerta (como detail) para manter as pessoas de usá-lo. Afinal, se ele só é útil para o programador, não há muita necessidade de escondê-lo muito - ninguém vai querer usá-lo de qualquer maneira

.

Talvez seja diferente em C ++ 0x (acho que eu ouvi alguns rumores como ele vai mudar as regras de acessibilidade entre aninhada e pai classe, ou então, caso em que nidificação pode ser mais vantajoso).

Para genericidade que você pode também querer fazer uso de modelos, e talvez acabar com Scheduler<A> (usando um TimedOperation<A>) (ou uma miríade de refinamentos potenciais / generalizações de que)?

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top