rendered paste body#include <iostream>template <typename rettype>class BaseCallbackConnection0{public: BaseCallbackConnection0() {} virtual rettype call() = 0;};template <typename rettype, typename arg1type>class BaseCallbackConnection1{public: BaseCallbackConnection1() {} virtual rettype call(arg1type arg) = 0;};template <class T, typename rettype>class CallbackConnection0 : public BaseCallbackConnection0<rettype>{public: CallbackConnection0() : BaseCallbackConnection0<rettype>() { m_obj = NULL; m_fn = NULL; } CallbackConnection0(T *obj, rettype (T::*fn)()) : BaseCallbackConnection0<rettype>() { m_obj = obj; m_fn = fn; } rettype call() { if (m_obj) return (m_obj->*m_fn)(); return rettype(); } T *m_obj; rettype (T::*m_fn)();};template <class T, typename rettype, typename arg1type>class CallbackConnection1 : public BaseCallbackConnection1<rettype, arg1type>{public: CallbackConnection1() : BaseCallbackConnection1<rettype, arg1type>() { m_obj = NULL; m_fn = NULL; } CallbackConnection1(T *obj, rettype (T::*fn)(arg1type)) : BaseCallbackConnection1<rettype, arg1type>() { m_obj = obj; m_fn = fn; } rettype call(arg1type arg1) { if (m_obj) return (m_obj->*m_fn)(arg1); return rettype(); } T *m_obj; rettype (T::*m_fn)(arg1type);};template <typename rettype>class Connection0{public: Connection0() { m_conn = 0; } template <typename T> void setCallback(T *obj, rettype (T::*fn)()) { if (m_conn) delete m_conn; m_conn = new CallbackConnection0<T, rettype>(obj, fn); } rettype call() { if (m_conn) return m_conn->call(); return rettype(); } BaseCallbackConnection0<rettype> *m_conn;};template <typename rettype, typename arg1type>class Connection1{public: Connection1() { m_conn = 0; } template <typename T> void setCallback(T *obj, rettype (T::*fn)(arg1type)) { if (m_conn) delete m_conn; m_conn = new CallbackConnection1<T, rettype, arg1type>(obj, fn); } rettype call(arg1type arg) { if (m_conn) return m_conn->call(arg); return rettype(); } BaseCallbackConnection1<rettype, arg1type> *m_conn;};class BaseFoo{public: BaseFoo() {} void callFoo() { fooFn.call(); } void callFoo1(int bar) { foo1Fn.call(bar); } int callFoo2(int bar) { return foo2Fn.call(bar); } template <class T> void setImplementation(T *obj) { fooFn.setCallback(obj, &T::doFoo); foo1Fn.setCallback(obj, &T::doFoo1); foo2Fn.setCallback(obj, &T::doFoo2); } Connection0<void> fooFn; Connection1<void, int> foo1Fn; Connection1<int, int> foo2Fn;};class BaseFooBarInterface{public: BaseFooBarInterface() {} void callFooBar(int *bar) { fooBarFn.call(bar); } template <class T> void setImplementation(T *obj) { fooBarFn.setCallback(obj, &T::doFooBar); } Connection1<void, int*> fooBarFn;};class FooImpl : public BaseFoo, public BaseFooBarInterface{public: FooImpl() : BaseFoo(), BaseFooBarInterface() { /* either use convenience methods to auto connect this to all "slots" * using pre defined method names */ BaseFoo::setImplementation(this); BaseFooBarInterface::setImplementation(this); /* ... or specify slots manually with whatever name comes to mind */ //fooFn.setCallback(this, &FooImpl::doFoo); //foo1Fn.setCallback(this, &FooImpl::doFoo1); //foo2Fn.setCallback(this, &FooImpl::doFoo2); //fooBarFn.setCallback(this, &FooImpl::doFooBar); } void doFoo() { std::cout << "FooImpl::doFoo called" << std::endl; } void doFoo1(int bar) { std::cout << "FooImpl::doFoo1 called with arg=" << bar << std::endl; } int doFoo2(int bar) { std::cout << "FooImpl::doFoo2 called with arg=" << bar << std::endl; return bar; } void doFooBar(int *barOut) { std::cout << "FooImpl::doFooBar called" << std::endl; if (barOut) *barOut = 0xff; }};int main(int argc, char **argv){ FooImpl impl; impl.callFoo(); impl.callFoo1(1); std::cout << "doFoo2 return=" << impl.callFoo2(2) << std::endl; int bar; impl.callFooBar(&bar); std::cout << "doFooBar return=" << bar << std::endl; return 0;}