类成员函数指针

Fly*_*man 7 c++ function-pointers arduino

我正在尝试使用类函数(中断服务例程),

void (ClassName::*fp)(void)=ClassName::FunctionName;
Run Code Online (Sandbox Code Playgroud)

并使用具有以下类型输入的功能将其连接到Arduino中断引脚,但不起作用.

void attachInterrupt(int, void (*)(void),int);
Run Code Online (Sandbox Code Playgroud)

我怎样才能做到这一点?中断服务例程(ISR)需要访问私有对象数据,因此我无法在类之外创建函数.

我的编译错误:

ClassName.cpp : : In constructor 'ClassName::ClassName()':
ClassName.cpp : *)()'
ClassName.cpp : *)()' to 'void (*)()' for argument '2' to 'void attachInterrupt(uint8_t, void (*)(), int)'
Run Code Online (Sandbox Code Playgroud)

注意:我正在课堂上寻找解决方案,并接受向我展示解决方案的答案,或者告诉我这是不可能的.

And*_*owl 6

如果函数不是static,则不能将其输入传递给接受非成员函数指针的函数.

考虑非static成员函数具有ClassName作为其第一个参数的隐式指针,该指针指向调用成员函数的对象.

struct X
{
    static void foo() { } // Does not have an implicit "this" pointer argument
    void bar() { } // Has an implicit "this" pointer argument
};

int main()
{
    void (*f)() = &X::foo; // OK: foo is static
    void (*g)() = &X::bar; // ERROR! bar is non-static
}
Run Code Online (Sandbox Code Playgroud)

在这里,甚至std::bind()都不会起作用,因为结果不能转换为函数指针.Lambdas可以转换为函数指针,但只有它们是非捕获的(并且这里的lambda需要捕获对象以调用成员函数).

因此,唯一(丑陋)的解决方法是使用全局适配器函数,该函数调用可通过全局指针变量获得的对象上的成员函数.在调用函数之前设置全局指针变量:

struct X
{
    void bar() { }
};

void function_taking_a_function_pointer(void (*f)())
{
    // Do something...
    f();
}

X* pX = nullptr;
void bar_adapter()
{
    pX->bar();
}

int main()
{
    X x; // Some object I want to invoke the member function bar() on...

    pX = &x; // Set the global pointer and invoke the function...
    function_taking_a_function_pointer(bar_adapter);
}
Run Code Online (Sandbox Code Playgroud)

如果需要,可以通过转换bar_adapter为函数模板,并将指针指向成员函数作为模板参数传递,使其更加灵活:

template<typename T, void (T::*mf)()>
void adapter()
{
    (pX->*mf)();
}
Run Code Online (Sandbox Code Playgroud)

以下是如何使用它:

#include <iostream>

struct X
{
    void foo() { std::cout << "X::foo()" << std::endl; }
    void bar() { std::cout << "X::bar()" << std::endl; }
};

void function_taking_a_function_pointer(void (*f)())
{
    // Do something...
    f();
}

X* pX = nullptr;

template<typename T, void (T::*mf)()>
void adapter()
{
    (pX->*mf)();
}

int main()
{
    X x; // Some object I want to invoke the member function bar() on...

    pX = &x; // Set the global pointer and invoke the function(s)...

    function_taking_a_function_pointer(adapter<X, &X::foo>);
    function_taking_a_function_pointer(adapter<X, &X::bar>);
}
Run Code Online (Sandbox Code Playgroud)

最后,这是一个实例.