¿Necesito crear una devolución de llamada simple en c ++? ¿Debo usar boost :: function?

StackOverflow https://stackoverflow.com/questions/611892

  •  03-07-2019
  •  | 
  •  

Pregunta

Supongamos que tengo un 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();
}

Necesito crear una devolución de llamada simple que se llamará cada vez que se llame al Visitor :: visit (). Sé que probablemente debería poner el código de la devolución de llamada dentro de mi Visitante, pero está en un contexto diferente, por lo que me gustaría pasar la función callBackFunction () al Visitante para que pueda invocar mi función de devolución de llamada.

Busqué cosas en la web y vi boost :: function, pero c ++ ya tiene los functores básicos.

¿Cuál debo usar para una mejor claridad del código? La devolución de llamada será una simple función void (), pero podría crecer, nunca se sabe el futuro :)

¿Cuál es la forma recomendada de hacer esto?

¿Fue útil?

Solución

Puede utilizar la interfaz de devolución de llamada y su jerarquía si no desea utilizar la función boost ::.

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

Si tiene o puede usar la función boost ::, úsela, es una buena manera de deshacerse de todas esas clases de devolución de llamada.

Editar:
@edisongustavo:

boost :: function and boost :: bind probablemente no hará que su código sea más legible. Pero le dará la oportunidad de pasar funciones libres (me refiero a funciones fuera de clase y funciones de clase estática) como devolución de llamada, así como funciones existentes de cualquier clase.

Con las funciones de refuerzo, puede pasar funciones con, por ejemplo, 2 parámetros como devolución de llamada que esperan solo un parámetro.

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

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

Pero, de nuevo, esto no hará que su código sea más legible a menos que todo su equipo sepa y favorezca el impulso.

Otros consejos

Sí, la función boost :: haría esto bien. Ese es un uso muy común. Deberá usar boost :: bind para vincular la instancia a la función miembro.

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

Sería cómo lo harías desde dentro de la clase.

Asegúrese de que " esto " no desaparece o su función de impulso se bloqueará en medio de algún encabezado de impulso en alguna parte.

Las respuestas anteriores son geniales, pero me gustaría señalar algo que mencionó en su pregunta, que todavía es relevante para su elección entre los objetos de devolución de llamada de C ++ (en la respuesta de Mykola) y aumentar.

" la devolución de llamada será una simple función void (), pero podría crecer, nunca se sabe el futuro:) "

Esta es probablemente la peor razón para una funcionalidad adicional e innecesaria, es decir, en caso de que la necesite. Si no sabe, entonces no haga más de lo necesario, es probable que adivine de todos modos, especialmente cuando lo necesite.

Por otro lado, si sabe que es extremadamente probable que necesite la funcionalidad muy pronto , entonces podría valer la pena agregarla.

Nuevamente para repetir lo que dijo Mykola: si ya tienes un impulso en tu proyecto y a tu equipo le gusta, entonces úsalo, pero de lo contrario puede ser excesivo.

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