All pastes #675306 Raw Edit

Unnamed

public text v1 · immutable
#675306 ·published 2007-08-30 00:14 UTC
rendered paste body
class Base;
class Child;
class B;
class C;

template<class Class, typename ParamType>
class Callback
{
private:
    typedef void (Class::*Method)(ParamType);
    Method m_method;
public:
    Callback(Method method) : m_method(method) {}
    void Execute(Class *c, ParamType p) { (c->*m_method)(p); }
};

class Dummy
{
};

class A
{
public:
    typedef void (A::*Method)(Dummy *obj, Callback<Dummy, B*> cb, Callback<Dummy, C*> cc);
    //typedef void (A::*Method)(Child *obj, Callback<Child, B*> cb, Callback<Child, C*> cc);
    Method m_method;
    A(Method m) : m_method(m) {}
    //virtual void Call(Child *obj, Callback<Child, B*> cb, Callback<Child, C*> cc) = 0;
    template<class Class>
        void ACall(Class *obj, void (Class::*methodB)(B*), void (Class::*methodC)(C*))
    {
        typedef void (Dummy::*MethodB)(B*);
        typedef void (Dummy::*MethodC)(C*);
        MethodB b = *((MethodB*)(&methodB));
        MethodC c = *((MethodC*)(&methodC));
        (this->*m_method)((Dummy*)obj, Callback<Dummy, B*>(b), Callback<Dummy, C*>(c));
    }
};

class B : public A
{
public:
    void BCall(Child *obj, Callback<Child, B*> cb, Callback<Child, C*> cc)
    {
        cb.Execute(obj, this);
    }
    B() : A((A::Method)&B::BCall) {}
};

class C : public A
{
public:
    void CCall(Child *obj, Callback<Child, B*> cb, Callback<Child, C*> cc)
    {
        cc.Execute(obj, this);
    }
    C() : A((A::Method)&C::CCall) {}
};

class Base
{
protected:
    virtual void F1(A *p) = 0;
};

class Child : public Base {
public:
    void F1(A *p)
    {
        p->ACall(this, &Child::F1B, &Child::F1C);
    }

    void F1B(B *p) { printf("Child B!\n"); }
    void F1C(C *p) { printf("Child C!\n"); }
};

void main()
{
    Child x;
    B b;
    x.F1(&b);
    C c;
    x.F1(&c);
    getch();
}