类的成员函数指针 [英] Class member function pointer
问题描述
我试图用一个类函数(中断服务程序)
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)需要访问普里瓦对象数据,所以我不能让课堂之外的功能。
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.
推荐答案
如果功能不静态
,你不能在输入传递给接受一个非功能-member函数指针。
If the function is not static
, you cannot pass it in input to a function that accepts a non-member function pointer.
考虑到非 - 静态
成员函数有一个隐含的指针类名
作为第一个参数,这点的对象在其上成员函数被调用
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
成一个函数的模板的,并通过指针到成员-function作为一个模板参数:
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屋!