首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何从class1向class2发送函数地址

如何从class1向class2发送函数地址
EN

Stack Overflow用户
提问于 2019-01-03 21:56:52
回答 1查看 60关注 0票数 0

c++11 / arm编译器v6.9 / keil5

我有两个类( class1,class2 )-我想从class1发送一个函数地址到第二个类,但我不能-我必须将我的函数定义为静态的-但我不想这样做

代码语言:javascript
复制
// ---------------------------- CLASS1.CPP ----------------------------
void CLASS1::ControlTransfer(uint8_t Physical_EPn, uint8_t bEPStatus) {
 // ...
}

void CLASS1::init() {
    class2.intHandler(2, ControlTransfer); // error: reference to non-static member function must be called
}

// ---------------------------- CLASS2.H ----------------------------
typedef void (TFnEPIntHandler)  (uint8_t Physical_EPn, uint8_t bEPStatus);

// ---------------------------- CLASS2.CPP ----------------------------
TFnEPIntHandler *_apfnEPIntHandlers[16];

void CLASS2::intHandler( uint8_t num, TFnEPIntHandler *pfnHandler ) {
    _apfnEPIntHandlers[ num ] = pfnHandler;
}

// _apfnEPIntHandlers used in my interrupt function
EN

回答 1

Stack Overflow用户

发布于 2019-01-03 22:19:58

在不知道调用哪个CLASS1对象的情况下,不能调用像CLASS1::ControlTransfer这样的非静态成员函数。像TFnEPIntHandler这样的函数的原始指针并不包含足够的信息来指定该对象。

如果可以,请考虑将原始函数指针更改为更灵活的std::function类型:

代码语言:javascript
复制
// In a header file:
#include <functional>
using TFnEPIntHandler = std::function<void(uint8_t, uint8_t)>;

// TFnEPIntHandler should now be used directly, not as a pointer.
// (Note a std::function can "act like" a null pointer.)
TFnEPIntHandler _apfnEPIntHandlers[16];
void CLASS2::intHandler( uint8_t num, TFnEPIntHandler pfnHandler ) {
    _apfnEPIntHandlers[ num ] = std::move(pfnHandler);
}

// Replace CLASS1::init():
void CLASS1::init() {
    // Use a lambda which captures the "this" pointer and can be
    // converted to the std::function type.  The function must not
    // be used after this CLASS1 object is destroyed!
    class2.intHandler(2, [this](uint8_t Physical_EPn, uint8_t bEPStatus)
        { ControlTransfer(Physical_EPn, bEPStatus); });
}

如果因为需要与C代码接口而不能选择std::function,那么可以向函数类型添加一个额外的void*参数,并使用包装函数将该指针转换为指向类类型的指针来调用真正的非静态成员函数。例如:

代码语言:javascript
复制
class CLASS1 {
// ...
private:
    static void ControlTransferCB(uint8_t Physical_EPn,
                                  uint8_t bEPStatus,
                                  void* extra)
    {
        static_cast<CLASS1*>(extra)->ControlTransfer(Physical_EPn, bEPStatus);
    }
// ...
};

额外的void*参数可以提供给CLASS2::intHandler (这意味着应该有一个函数指针的结构数组和额外的void*数据),或者提供给实际调用函数的其他逻辑,以更合适的方式为准。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/54023744

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档