Zum Zerpfücken



  • using namespace std;
    
    class A { public: virtual ~A() {}}; class B : public A {};
    
    class Base {
    public:
        typedef void (*FZ) (Base*,void*);
        static map<const type_info *, FZ> x;
    
        template <class T>
        void eat (T *a) {
            if (x.find(&typeid(*a)) != x.end()) x[&typeid(*a)](this,a);
            else return;
        }
    
        virtual ~Base () {}
    };
    map<const type_info *, Base::FZ> Base::x;
    
    void Helper (void*,void*);
    class Derived : public Base {
    public:
        struct HelperS {
            HelperS ();
        };
        static HelperS h;
    
        void eat (B *b) {
            cout << "B::eat\n";
        }
    };
    void Helper (Base *a, void *b) {
        (dynamic_cast<Derived*>(a))->eat((B*)(b));
    }
    
    Derived::HelperS Derived::h;
    Derived::HelperS::HelperS ()  {
        Base::x[&typeid(B)] = Helper;
    }
    
    int main () {
        Derived d; Base &bd = d;
        A a; B b;
    
        bd.eat (&a);
        bd.eat (&b);
    }
    

    Ich hoffe, ihr versteht, was der Code macht.
    Mir ist das allerdings zu gefährlich, vor allem auch wegen des C-Casts, aber auf void* darf ich ja keinen dynamic_cast anwenden.
    Ich hoffe ebenfalls, ihr kennt eine andere (schöne) Methode, um das Problem zu lösen.
    Ich will nur:

    class A { public: virtual ~A() {}}; class B : public A {}; //zwei Helferklassen
    
    class Base {
    public:
       virtual void * eat (A *);
    };
    
    class Derived {
    public:
       void eat (B *);
    };
    

    Ich will, das Derived::eat aufgerufen wird, wenn ich so mache:

    int main () {
       Derived d; Base &bd = d;
       B b; 
       A a;
       bd.eat (&a); //soll Base::eat (A*) aufrufen
       bd.eat (&b); //soll Derived::eat (B*) aufrufen
    }
    

    Geht das nicht einfacher, als mein Workaround?



  • mit using die ueberlagerte methode sichtbar machen.


Anmelden zum Antworten