简体   繁体   English

在基类中,如何定义一个包含函数obj的容器,它可以是派生类的任何函数?

[英]in base class, how to define a container to contain function obj which can be any func of derived class?

I want to define a container in the base class, which contains function obj or anything that can make my purpose happen. 我想在基类中定义一个容器,其中包含函数obj或任何可以实现我的目的的东西。 These function obj can call derived classes' functions. 这些函数obj可以调用派生类的函数。 they all take same parameters. 它们都采用相同的参数。

#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);
}

Here's a way to achieve what your code looks like it's trying to do, without using function pointers: 这是一种无需使用函数指针即可实现代码所要执行的功能的方法:

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();
}

Now, there may well be reasons to do this completely differently, but I don't see why you should need both virtual functions and inheritance, AND function objects/function pointers. 现在,完全有理由完全不同地执行此操作,但是我不明白为什么您既需要虚拟函数又需要继承以及AND函数对象/函数指针。 That seems quite wrong to me ("smells bad") 对我来说,这似乎很不对劲(“闻起来不好”)

Edit: 编辑:

Here's something I came up with, that solves the type of problem you describe after edits of the original question. 这是我想出的,它可以解决您对原始问题进行编辑后描述的问题类型。

#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);
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何从包含基类指针的容器中调用派生类函数(基于其类型)? - How to call derived class function (based on its type) from a container which contain pointer of base class? 如何在没有派生类中显式调用Base :: func()的情况下从基类执行虚函数? - How to execute a virtual function from a base class without the explicit call of Base::func() in a derived class? 在多态中如何访问派生类而不是基类中定义的函数 - How to access the function which is defined in derived class and not in base class in polymorphism 如何分辨哪个派生类对象称为基类函数 - How to tell which derived class object called a base class function 指向由派生 class 初始化的 Base class 的指针如何可以将 *__vptr 称为正确的虚拟 function? - How does a pointer to a Base class which initialized by a derived class can have *__vptr called the right virtual function? 如何使用派生类实例调用基类重载func, - How to call base class overloaded func using derived class instance, 派生类函数如何调用基类的函数? - how can a derived class function call a function of the base class? 无法定义枚举类型的 function,它在派生的 class 的基础 class 中声明(公共) - Cannot define function of type enum which is declared (public) in base class in derived class 如何在派生类中重用基类函数 - How can I reuse a base class function in a derived class 我如何在基类中为派生类函数做朋友? - How can I friend a derived class function in the base class?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM