从另一个类传递指向私有成员函数的指针

时间:2018-11-08 15:03:17

标签: c++ pointers casting

我想为类创建一些回调函数。回调应该不是静态的,才能访问私有成员变量。 为了更好地理解,我举了一个简短的示例来开发此功能。我的问题是该函数指针适用于无类函数,但不适用于私有成员函数

我使用printf("%p", cb)验证了函数指针地址本身是正确的

main.cpp

#include <cstdlib>
#include <cstdio>

typedef void f_t (int);

class First {
    public:
        First(void(cb)(int type)) { mFunc = cb; }
        void start(int type) { (mFunc)(type); }

    private:
        f_t* mFunc;
};

class Second {
    public:
        Second() {};

        void start() {
            //First *my = new First((void(*)(int))&Second::onEvt);
            First *my = new First(reinterpret_cast<f_t*>(&Second::onEvt));
            my->start(123);
        }

    private:
        void onEvt(int type) {
            printf("onEvt type: %d\n", type);
        }

};


void onEvt2(int type) {
    printf("onEvt2 type: %d\n", type);
}

int main() {
    First *my = new First((void(*)(int))&onEvt2);
    my->start(456);

    Second *sec = new Second();
    sec->start();

    return 0;
}

结果是:

onEvt2 type: 456                                                                                                 
onEvt type: 0

我尝试了不同的投射方式,但是没有任何效果。我不确定是否要在正确的课程上讲课,也许我必须在First课程上讲课

完全有可能具有这样的功能吗?

此功能应与wxCommandEventHandler库中的wxWidgets几乎相同。

谢谢您的帮助。

编辑-已解决

链接重复项中的第一个答案是解决方案。这是我的工作示例:

#include <cstdlib>
#include <cstdio>
#include <functional>

using namespace std::placeholders; // for `_1`


class First {
    public:
        First(std::function<void(int)> cb) { mFunc = cb; }
        void start(int type) { (mFunc)(type); }

    private:
        std::function<void(int)> mFunc;
};

class Second {
    public:
        Second() {};

        void start() {
            First *my = new First(std::bind(&Second::onEvt, this, _1));
            my->start(123);
            my->start(456);
        }

    private:
        void onEvt(int type) {
            printf("onEvt type: %d\n", type);
        }

};

void onEvt2(int type) {
    printf("onEvt2 type: %d\n", type);
}

int main() {
    First *my = new First(onEvt2);
    my->start(789);

    Second *sec = new Second();
    sec->start();

    return 0;
}

0 个答案:

没有答案