#include <list>
#include <utility>
#include <iostream>
class Base
{
public:
void doForAllDerived()
{
for (handlerList_t::const_iterator it = _registeredHandlers.begin(); it != _registeredHandlers.end(); ++it )
(it->second)( it->first, 5 );
}
protected:
typedef void(*PrepFn)(Base*, int);
typedef std::pair< Base *, PrepFn > handlerPair_t;
void registerPrepFn( PrepFn fn, Base * instance )
{
_registeredHandlers.push_back( handlerPair_t( instance, fn ) );
};
private:
typedef std::list< handlerPair_t > handlerList_t;
handlerList_t _registeredHandlers;
};
class Derived : public Base
{
public:
Derived() {
registerPrepFn( &Derived::derivedPrepFn, this );
};
protected:
static void derivedPrepFn( Base* b_ptr, int n )
{
Derived * p_d = static_cast<Derived *>( b_ptr );
p_d->realHandler( n );
};
void realHandler( int n ) { std::cout << n << std::endl;};
};
int main() {
Derived anInstance;
anInstance.doForAllDerived();
}
I2luY2x1ZGUgPGxpc3Q+CiNpbmNsdWRlIDx1dGlsaXR5PgojaW5jbHVkZSA8aW9zdHJlYW0+CgoKY2xhc3MgQmFzZQp7CnB1YmxpYzoKCXZvaWQgZG9Gb3JBbGxEZXJpdmVkKCkKCXsKCQlmb3IgKGhhbmRsZXJMaXN0X3Q6OmNvbnN0X2l0ZXJhdG9yIGl0ID0gX3JlZ2lzdGVyZWRIYW5kbGVycy5iZWdpbigpOyBpdCAhPSBfcmVnaXN0ZXJlZEhhbmRsZXJzLmVuZCgpOyArK2l0ICkKCQkJKGl0LT5zZWNvbmQpKCBpdC0+Zmlyc3QsIDUgKTsKCX0KCnByb3RlY3RlZDoKICAgIHR5cGVkZWYgdm9pZCgqUHJlcEZuKShCYXNlKiwgaW50KTsKICAgIHR5cGVkZWYgc3RkOjpwYWlyPCBCYXNlICosIFByZXBGbiA+IGhhbmRsZXJQYWlyX3Q7CiAgICB2b2lkIHJlZ2lzdGVyUHJlcEZuKCBQcmVwRm4gZm4sIEJhc2UgKiBpbnN0YW5jZSApCiAgICB7CiAgICAgICAgX3JlZ2lzdGVyZWRIYW5kbGVycy5wdXNoX2JhY2soIGhhbmRsZXJQYWlyX3QoIGluc3RhbmNlLCBmbiApICk7CiAgICB9OwogICAgCnByaXZhdGU6CiAgICB0eXBlZGVmIHN0ZDo6bGlzdDwgaGFuZGxlclBhaXJfdCA+IGhhbmRsZXJMaXN0X3Q7CiAgICBoYW5kbGVyTGlzdF90IF9yZWdpc3RlcmVkSGFuZGxlcnM7Cn07CiAKY2xhc3MgRGVyaXZlZCA6IHB1YmxpYyBCYXNlCnsKcHVibGljOgogICAgRGVyaXZlZCgpIHsKICAgICAgICByZWdpc3RlclByZXBGbiggJkRlcml2ZWQ6OmRlcml2ZWRQcmVwRm4sIHRoaXMgKTsKICAgIH07Cgpwcm90ZWN0ZWQ6CiAgICBzdGF0aWMgdm9pZCBkZXJpdmVkUHJlcEZuKCBCYXNlKiBiX3B0ciwgaW50IG4gKQogICAgewogICAgICAgIERlcml2ZWQgKiBwX2QgPSBzdGF0aWNfY2FzdDxEZXJpdmVkICo+KCBiX3B0ciApOwogICAgICAgIHBfZC0+cmVhbEhhbmRsZXIoIG4gKTsKICAgIH07CiAKICAgIHZvaWQgcmVhbEhhbmRsZXIoIGludCBuICkgeyBzdGQ6OmNvdXQgPDwgbiA8PCBzdGQ6OmVuZGw7fTsKIAp9OwogCmludCBtYWluKCkgewogICAgRGVyaXZlZCBhbkluc3RhbmNlOwogICAgYW5JbnN0YW5jZS5kb0ZvckFsbERlcml2ZWQoKTsKfQo=