类成员函数指针 [英] Class member function pointer

查看:26
本文介绍了类成员函数指针的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm trying to use a class function (interrupt service routine),

void (ClassName::*fp)(void)=ClassName::FunctionName;

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

and attaching it to an Arduino interrupt pin using the function with the following type inputs but that doesn't work.

void attachInterrupt(int, void (*)(void),int);

我怎样才能做到这一点?中断服务例程(ISR)需要访问privat对象数据,所以我不能在类之外做一个函数.

How can I make this happen? The interrupt service routine (ISR) needs to access privat object data, so I can't make a function outside of the class.

我的编译器错误:

ClassName.cpp : : In constructor 'ClassName::ClassName()':
ClassName.cpp : *)()'
ClassName.cpp : *)()' to 'void (*)()' for argument '2' to 'void attachInterrupt(uint8_t, void (*)(), int)'

注意:我正在课堂内寻找解决方案,并且会接受向我展示解决方案或向我展示不可能的答案.

Note: I am looking for a solution inside the class and will accept the answer that shows me a solution or shows me it's not possible.

推荐答案

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

If the function is not static, you cannot pass it in input to a function that accepts a non-member function pointer.

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

Consider that a non-static member function has an implicit pointer to ClassName as its first parameter, which points to the object on which the member function is being invoked.

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
}

在这里,即使 std::bind() 也不起作用,因为结果不能转换为函数指针.Lambda 可以转换为函数指针,但前提是它们是非捕获的(这里的 lambda 需要捕获对象以调用成员函数).

Here, not even std::bind() will work, because the result is not convertible to a function pointer. Lambdas are convertible to function pointers, but only if they are non-capturing (and a lambda here would need to capture the object to invoke the member function on).

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

Therefore, the only (ugly) workaround is to have a global adapter function which invokes the member function on an object which is available through a global pointer variable. The global pointer variable is set prior to calling the function:

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

如果需要,您可以通过将 bar_adapter 转换为函数 template 并将指向成员函数的指针作为模板参数传递来使其稍微灵活一些:

If you want, you can make this slightly more flexible by turning bar_adapter into a function template, and passing the pointer-to-member-function as a template argument:

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

以下是您将如何使用它:

Here is how you would use it:

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

最后,这是一个现场示例.

这篇关于类成员函数指针的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆