0

我想在基类中定义一个容器,其中包含函数 obj 或任何可以实现我的目的的东西。这些函数 obj 可以调用派生类的函数。它们都采用相同的参数。

#include <vector>
#include <functional>
#include <iostream>


class Foo {
    Foo() {}
    virtual ~Foo(){}

    virtual void init()
    { registerCallback(0, &Foo::print_ori ); }
    void print_ori(int i) const { std::cout << i << '\n'; }

    void registerCallback(int key, ??? cb ) // NOT SURE HOW TO DEFINE THIS
    {
        callbacks[key] = cb;
    }

    void runCallbacks(int key, int n)
    {
        auto i = callbacks.find(key);
        if (i != callbacks.end()) {
            (*i)(*this, n);
        }
    }

    std::map<int, std::function<void(const Foo&, int) > > callbacks; // obviously, it's wrong. how to fix it?
};
struct Foo2 : public Foo {
    Foo2(int num) : Foo(num) {}
    virtual void init()
    {
        Foo::init();
        registerCallback(11, &Foo2::print1 );
        registerCallback(12, &Foo2::print2 );
    }
    void print1(int i) const { std::cout << " - Foo2.p1 - " << i << endl; }
    void print2(int i) const { std::cout << " - Foo2.p2 - " << i << endl; }
};



int main()
{
    Foo* obj = new Foo2();
    obj->init();
    obj->runCallbacks(12, 456);
}
4

1 回答 1

1

这是一种无需使用函数指针即可实现代码看起来想要做的事情的方法:

class Foo {
    Foo() {}
    virtual ~Foo(){}

    void print_ori(int i) const { std::cout << i << '\n'; }

    virtual void do_runCallbacks(int v)
    {
    }

    void runCallbacks()
    {
        print_ori(3)
        do_runCallBacks(3);
    }

};
struct Foo2 : public Foo {
    Foo2(int num) : Foo(num) {}

    void do_runcallbacks(int v)
    {
       print1(v);
       print2(v);
    }
    void print1(int i) const { std::cout << " - Foo2.p1 - " << i << endl; }
    void print2(int i) const { std::cout << " - Foo2.p2 - " << i << endl; }
};



int main()
{
    Foo* obj = new Foo2();
    obj->runCallbacks();
}

现在,很可能有理由完全不同地这样做,但我不明白为什么你应该同时需要虚函数和继承,以及函数对象/函数指针。这对我来说似乎很不对劲(“闻起来很糟糕”)

编辑:

这是我想出的东西,它解决了您在编辑原始问题后描述的问题类型。

#include <iostream>
#include <map>

using namespace std;

class event_interface
{
public:
    virtual void action(int n) = 0;
};

class event_manager
{
public:
    event_manager(int n) : num(n) {}
    void register_event(int key, event_interface *eh) 
    { 
        handlers[key] = eh; 
    }
    void callback(int key)
    {
        auto h = handlers.find(key);
        if (h != handlers.end())
        {
        h->second->action(num);
        }
    }
private:
    map<int, event_interface *> handlers;
    int num;
};


class handler1 : public event_interface
{
public:
    void action(int n) { cout << "in handler1::action. n=" << n << endl; }
};

class handler2 : public event_interface
{
public:
    handler2(int n) : data(n) {}
    void action(int n) 
    { 
        cout << "in handler2::action. n=" << n 
         << " data = " << data << endl; 
    }
private:
    int data;
};

class multihandler 
{
private:
    class handler3: public event_interface
    {
    public:
    void action(int n) { cout << "in handler3::action. n=" << n << endl; }
    };

    class handler4: public event_interface
    {
    public:
    handler4(multihandler *m) : mh(m) {}
    void action(int n) 
        { 
        cout << "in handler4::action. n=" << n 
             << " data = " << mh->data << endl; 
        }
    private:
    multihandler* mh;
    };

public:
    multihandler(event_manager& em) : h4(this)
    {
        em.register_event(62, &h3);
        em.register_event(63, &h4);
        data = 42;
    }

private:
    handler3 h3;
    handler4 h4;
    int data;
};


int main()
{
    event_manager mgr(3);
    handler1 h1;
    handler2 h2(77);

    multihandler mh(mgr);

    mgr.register_event(12, &h1);
    mgr.register_event(13, &h2);

    int evts[] = { 12, 63, 62, 13, 18 };

    for(auto i : evts)
    {
    cout << "Event: " << i << endl;
    mgr.callback(i);
    }
}
于 2013-08-07T00:04:30.630 回答