2010-11-16 6 views
2

J'ai beaucoup de code hérité qui utilise un pointeur de fonction comme un argument de la forme double (*f)(double). Maintenant, j'ai une exigence où j'ai besoin d'appeler cette fonction à partir d'une classe, mais la définition de la fonction utilise des variables membres. Que dois-je faire pour résoudre ce problème? Par exemple,pointeur de fonction avec des arguments connus

void legacy_function(double (*f)(double)) { .... } 

class myclass { 
    double a; 
    double b; 
    double c; 

    void mymethod(...) { 
     // need to call legacy_function() such that it uses a and b with one unknown 
     // a+b*x 

    }  

Notez que je ne peux pas modifier les définitions ou les déclarations dans le code existant.

J'espère que cela a du sens. merci pour vos suggestions ..

+0

Si vous pouviez modifier le code existant, la fonction boost :: correspondrait. Voir http://www.boost.org/doc/libs/1_44_0/doc/html/function/tutorial.html#id1264562 –

Répondre

3

Il n'y a pas de moyen propre pour résoudre ce problème. Il n'a pas de solution élégante dans les limites de la langue standard. Une chose que vous pouvez faire est de fournir une variable globale ou statique qui servira de pointeur this pour la fonction d'encapsulation de rappel intermédiaire (voir ci-dessous), et d'écrire une fonction d'encapsuleur de rappel intermédiaire statique qui va décréter l'appel à un non méthode classe -static

class myclass { 
    ... 
    static myclass *myclass_this; 

    double callback_wrapper(double d) { 
    assert(myclass_this != NULL); 
    return myclass_this->callback(d); // calls the actual implementation 
    } 
}; 

écrire également la mise en œuvre de rappel réelle dans myclass

class myclass { 
    ... 
    double callback(double d) { 
    // do whatever you want with `a`, `b` etc. 
    return /* whatever */; 
    } 
    ... 
}; 

maintenant, vous pouvez initialiser myclass_this et utiliser l'inter médiation wrapper de rappel à l'intérieur mymethod

... 
void mymethod(...) { 
    myclass_this = this; // initilize the context 
    legacy_function(&callback_wrapper); 
} 
... 

Tout cela, bien sûr, est terriblement inélégante, car il repose sur des variables globales ou statiques et est donc non rentrante.

Il existe d'autres méthodes, qui sont toutes non portables et non standard. (Lire à propos de fermetures et delegates).

+0

+1 Je ne peux pas penser à une autre solution – icecrime