#include template class BaseCallbackConnection0 { public: BaseCallbackConnection0() {} virtual rettype call() = 0; }; template class BaseCallbackConnection1 { public: BaseCallbackConnection1() {} virtual rettype call(arg1type arg) = 0; }; template class CallbackConnection0 : public BaseCallbackConnection0 { public: CallbackConnection0() : BaseCallbackConnection0() { m_obj = NULL; m_fn = NULL; } CallbackConnection0(T *obj, rettype (T::*fn)()) : BaseCallbackConnection0() { 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 CallbackConnection1 : public BaseCallbackConnection1 { public: CallbackConnection1() : BaseCallbackConnection1() { m_obj = NULL; m_fn = NULL; } CallbackConnection1(T *obj, rettype (T::*fn)(arg1type)) : BaseCallbackConnection1() { 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 class Connection0 { public: Connection0() { m_conn = 0; } template void setCallback(T *obj, rettype (T::*fn)()) { if (m_conn) delete m_conn; m_conn = new CallbackConnection0(obj, fn); } rettype call() { if (m_conn) return m_conn->call(); return rettype(); } BaseCallbackConnection0 *m_conn; }; template class Connection1 { public: Connection1() { m_conn = 0; } template void setCallback(T *obj, rettype (T::*fn)(arg1type)) { if (m_conn) delete m_conn; m_conn = new CallbackConnection1(obj, fn); } rettype call(arg1type arg) { if (m_conn) return m_conn->call(arg); return rettype(); } BaseCallbackConnection1 *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 void setImplementation(T *obj) { fooFn.setCallback(obj, &T::doFoo); foo1Fn.setCallback(obj, &T::doFoo1); foo2Fn.setCallback(obj, &T::doFoo2); } Connection0 fooFn; Connection1 foo1Fn; Connection1 foo2Fn; }; class BaseFooBarInterface { public: BaseFooBarInterface() {} void callFooBar(int *bar) { fooBarFn.call(bar); } template void setImplementation(T *obj) { fooBarFn.setCallback(obj, &T::doFooBar); } Connection1 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; }