Je voulais pouvoir avoir quelque chose comme la sémantique d'interface de Java avec C++. Au début, j'avais utilisé boost::signal
pour rappeler des fonctions membres explicitement enregistrées pour un événement donné. Cela a très bien fonctionné. Mais alors j'ai décidé que certains groupes de rappels de fonctions étaient liés et qu'il était logique de les résumer et de les enregistrer pour toutes les fonctions de rappel associées d'une instance en même temps. Mais ce que j'ai appris, c'est que la nature spécifique de boost::bind
et/ou prendre la valeur de this
semblait faire cette pause. Ou peut-être que c'était juste le fait que la déclaration de la méthode add_listener(X &x)
a changé le code généré par boost::bind
. Je comprends très mal pourquoi le problème est survenu et je pense qu'il fonctionne probablement correctement selon sa conception. Je suis curieux: ce que devrait j'ai fait à la place? Il y a sûrement une bonne façon de le faire."Interface" comme sémantique avec boost :: bind
Voici quelques exemples de code:
#include <boost/bind.hpp>
#include <boost/function.hpp>
#include <iostream>
using namespace std;
struct X;
struct Callback
{
virtual void add_listener(X &x) = 0;
};
struct X
{
X() {}
X(Callback &c) { c.add_listener(*this); }
virtual void go() { cout << "\t'" << __PRETTY_FUNCTION__ << "'" << endl; }
};
struct CallbackReal : public Callback
{
virtual void add_listener(X &x)
{
f = boost::bind<void>(boost::mem_fn(&X::go), x);
}
void go() { f(); }
boost::function<void (void)> f;
};
struct Y : public X
{
Y() {}
Y(Callback &c) { c.add_listener(*this); }
virtual void go() { cout << "\t'" << __PRETTY_FUNCTION__ << "'" << endl; }
};
int main(void)
{
CallbackReal c_x;
CallbackReal c_y;
X x(c_x);
Y y(c_y);
cout << "Should be 'X'" << endl;
boost::bind<void>(boost::mem_fn(&X::go), x)();
cout << "Should be 'Y'" << endl;
boost::bind<void>(boost::mem_fn(&X::go), y)();
cout << "------------------" << endl;
cout << "Should be 'X'" << endl;
c_x.go();
cout << "I wish it were 'Y'" << endl;
c_y.go();
return 0;
}
D'accord, je ne l'ai pas décrire complètement le problème. Le titre est trompeur.
Oh, mec. Downvote celui-ci. Je n'ai évidemment pas bien décrit le problème et je pense que cela se résume finalement à une erreur syntaxique. :(
Quelle est la sortie? Des erreurs/avertissements du compilateur? –
Je suis confus quant à ce que la «sémantique de l'interface» a à voir avec ce que vous faites ici. Pourquoi n'utilisez-vous pas simplement des classes de base abstraites et des fonctions virtuelles? Voir: http://www.parashift.com/c++-faq-lite/abcs.html#faq-22.4 –
D'accord, il est clair pour moi maintenant que j'ai confondu quelques choses et donné des détails insuffisants dans mon exemple. Ce que je fais * vraiment *, c'est d'utiliser 'boost :: signal' pour appeler les différents gestionnaires enregistrés. Pour utiliser un exemple légèrement plus explicite, disons que j'ai une classe abstraite 'EventListener' avec les méthodes' handleFooEvent', 'handleBarEvent' et' handleBazEvent'. Je voudrais enregistrer une instance d'un 'EventListener' et connecter les méthodes' handle * Event' avec un emplacement correspondant. –