Я хотел иметь что-то вроде семантики интерфейса Java с C++. Сначала я использовал boost::signal
для обратного вызова явно зарегистрированных функций-членов для данного события. Это сработало очень хорошо.«Интерфейс», как семантика с boost :: bind
Но потом я решил, что некоторые пулы функций обратных вызовов были связаны, и имеет смысл их абстрагировать и регистрировать для всех связанных обратных вызовов экземпляра сразу. Но я узнал, что специфический характер boost::bind
и/или принятие значения this
, казалось, сделали этот перерыв. Или, возможно, именно факт, что объявление метода add_listener(X &x)
изменило код, созданный boost::bind
.
У меня очень грубое понимание, почему возникла проблема, и я думаю, что это, вероятно, работает правильно в соответствии с его дизайном. Мне любопытно: что должно Я сделал вместо этого? Конечно, есть правильный способ сделать это.
Вот пример кода:
#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;
}
Хорошо, я не описал проблему полностью. Название вводит в заблуждение.
О, мужчина. Снизьте это. Я, очевидно, не очень хорошо описывал проблему, и я думаю, что это в конечном итоге сводится к синтаксической ошибке. :(
Какой выходной сигнал? Любые ошибки/предупреждения компилятора? –
Я смущен, что «семантика интерфейса» связана с тем, что вы здесь делаете. Почему бы вам просто не использовать чистые абстрактные базовые классы и виртуальные функции? Смотрите: http://www.parashift.com/c++-faq-lite/abcs.html#faq-22.4 –
Хорошо, теперь мне ясно, что я собрал несколько вещей и дал недостаточно подробностей в моем примере. То, что я действительно делаю, использует 'boost :: signal' для вызова различных зарегистрированных обработчиков. Чтобы использовать более откровенный пример, допустим, у меня есть абстрактный класс EventListener с методами 'handleFooEvent',' handleBarEvent' и 'handleBazEvent'. Я хотел бы зарегистрировать экземпляр «EventListener» и связать эти методы 'handle * Event' с каждым слотом. –