Pergunta

Suponha que eu tenho algum código como este:

class Visitor {
   public:
      Visitor(callBackFunction) {}
      void visit() {
          //do something useful
          invokeCallback();
      }
}

class ClassThatCanBeVisited {
    Visitor &visitor;

    public:
       ClassThatCanBeVisited(Visitor &_visitor) : visitor(_visitor){}
       void someUsefulMethod() {
          int data= 42;
          visitor.visit(data);
       }
};


void callBackFunction() {
    //do something useful in the context of the Main file
}
int main() {
     Visitor visitor;
     ClassThatCanBeVisited foo(visitor);
     foo.someUsefulMethod();
}

Eu preciso criar um callback simples que será chamado sempre que o Visitante :: visita () é chamado. Eu sei que eu provavelmente deveria colocar o código do retorno dentro de meu visitante, mas é em um contexto diferente, então eu gostaria de passar o callBackFunction () para o visitante para que ele pudesse chamar a minha função de retorno de chamada.

Eu olhei para as coisas no boost :: função web e serra, mas c ++ já tem os functors básicas.

Qual deles devo usar para melhor clareza do código? O retorno de chamada vai ser uma função simples void (), mas pode crescer, você nunca sabe o futuro:)

O que é a maneira recomendada para fazer isso?

Foi útil?

Solução

Você pode usar a interface de retorno de chamada e sua hierarquia, se você não quiser usar boost :: função.

class VisitorCallback
{
public:
    virtual void handle( const Visitor& ) = 0;
};

Se você tem ou pode usar boost :: função -. Usá-lo, é uma boa maneira de se livrar de todas as classes de retorno de chamada

Editar:
@edisongustavo:

boost :: função e boost :: bind não vai provavelmente tornar o código mais legível. Mas ele vai te dar a oportunidade de passar funções livres (I funções médios fora da classe e funções de classe estáticos) como callback, bem como funções existentes de qualquer classe.

Com funções impulso que você pode passar funções com por exemplo 2 parâmetros como callback que esperar apenas um parâmetro.

typedef boost::function< void ( int ) > IntExpectingCallback;

void TwoIntFunction( int, int );
{
}
...
IntExpectingCallback callback = boost::bind( TwoIntFunction, 5, _1 );

Mas, novamente, isso não vai fazer seu código mais legível, a menos que toda a sua equipe sabe e favor impulso.

Outras dicas

Sim boost :: função seria fazer isso bem. Isso é um uso muito comum dele. Você vai precisar usar boost :: bind para vincular a instância para a função de membro.

 func = boost::bind( &MyClass::CallbackFunc, this);

Seria como você faria isso de dentro da classe.

Certifique-se a "isto" não desaparecer ou a sua função de aumento irá falhar no meio de algum lugar impulso cabeçalho.

As respostas acima são grandes, mas eu gostaria de salientar algo que você mencionou na sua pergunta, que ainda é relevante para a sua escolha entre C ++ objetos de retorno de chamada (em resposta de Mykola) e impulso.

"a chamada de retorno vai ser uma função simples void (), mas pode crescer, você nunca sabe o futuro :)"

Este é provavelmente o pior motivo para a funcionalidade extra, desnecessário - que é "apenas no caso de você precisar dele". Se você não sabe - então não fazer mais do que é necessário, é provável que o seu palpite será de qualquer maneira errada, especialmente pelo tempo que você precisar dele

.

Por outro lado, se você sabe que é muito provável que você vai precisar da funcionalidade muito em breve , então pode valer a pena adicioná-lo.

Mais uma vez de reiterar que Mykola disse -. Se você já tem impulso em seu projeto e sua equipe gosta dele, então use isso, mas caso contrário, pode ser um exagero

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