Domanda

Supponiamo di avere un codice come questo:

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();
}

Devo creare un semplice callback che verrà chiamato ogni volta che viene chiamato Visitor :: visit (). So che probabilmente dovrei inserire il codice del callback nel mio visitatore, ma si trova in un contesto diverso, quindi vorrei passare il callBackFunction () al visitatore in modo che possa invocare la mia funzione di callback.

Ho cercato cose sul web e ho visto boost :: function, ma c ++ ha già i funzioni di base.

Quale dovrei usare per una migliore chiarezza del codice? Il callback sarà una semplice funzione void (), ma potrebbe crescere, non si conosce mai il futuro :)

Qual è il modo consigliato per farlo?

È stato utile?

Soluzione

Puoi usare l'interfaccia di callback e la sua gerarchia se non vuoi usare boost :: function.

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

Se hai o puoi usare la funzione boost :: - usala, è un buon modo per sbarazzarti di tutte quelle classi di callback.

Modifica:
@edisongustavo:

boost :: function e boost :: bind probabilmente non renderanno il tuo codice più leggibile. Ma ti darà l'opportunità di passare funzioni gratuite (intendo funzioni fuori classe e funzioni di classe statiche) come callback e funzioni esistenti di qualsiasi classe.

Con le funzioni boost è possibile passare funzioni come ad esempio 2 parametri come callback che prevedono solo un parametro.

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

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

Ma ancora una volta, questo non renderà il tuo codice più leggibile a meno che tutto il tuo team non lo sappia e favorisca il boost.

Altri suggerimenti

Sì boost :: la funzione farebbe bene. Questo è un uso molto comune di esso. Dovrai utilizzare boost :: bind per associare l'istanza alla funzione membro.

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

Sarebbe come lo faresti all'interno della classe.

Assicurati che " questo " non scompare o la tua funzione boost si bloccherà nel mezzo di qualche header boost da qualche parte.

Le risposte di cui sopra sono ottime, ma vorrei solo sottolineare qualcosa che hai menzionato nella tua domanda, che è ancora rilevante per la tua scelta tra oggetti di callback C ++ (nella risposta di Mykola) e boost.

" il callback sarà una semplice funzione void (), ma potrebbe crescere, non si conosce mai il futuro:) "

Questo è probabilmente il motivo peggiore per funzionalità extra, non necessarie, vale a dire "nel caso in cui ne abbiate bisogno". Se non lo sai, allora non fare più del necessario, è probabile che la tua ipotesi sarà comunque sbagliata, soprattutto quando ne avrai bisogno.

D'altra parte, se sai che è estremamente probabile che avrai bisogno della funzionalità molto presto , allora varrebbe la pena aggiungerlo.

Ancora una volta per ripetere ciò che Mykola ha detto: se hai già una spinta nel tuo progetto e il tuo team piace, allora usalo, ma altrimenti potrebbe essere eccessivo.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top