我有一个类X,它具有以下方法:
void setRxHandler(void (*h)(int));我想向它传递一个存在于类Y实例中的成员函数。
void comm_rxHandler(int status);我尝试了以下几点:
x.setRxHandler(comm_rxHandler) 但是它得到了以下编译错误(我使用的是Qt):
错误:没有匹配函数调用‘X::setRxHandler(<未解析重载函数type>)’
那我该怎么做呢?
我注意到,如果我声明comm_rxHandler (类Y)为静态的,我没有错误。但我希望comm_rxHandler是一种非静态的方法。另外,我希望setRxHandler方法(类X)是通用的,而不是特定于类的。所以我不能把这个方法声明为:
setRxHandler(void (Y::*h)(int))怎么做?你能帮我吗?
谢谢!
发布于 2011-07-30 16:54:32
与现在一样,setRxHandler原型接受一个指向不返回任何内容并接受int的函数的指针。正如您已经注意到的,这将不适用于成员函数,因为它们不能像普通函数那样被调用(您还必须处理this指针,这意味着有一个该类的实例来调用方法)。
要使它既可用于成员函数,也可用于非特定(泛型),您必须创建一个基类,并将所有要使用setRxHandler的类与该类的派生一起使用:
class Base { ... };
class Derived : public Base { ... };
// then for the prototype
void setRxHandler(void (Base::*h)(int)) { ... }
// and you can use setRxHandler for all types that derive from Base, which gives you more control than the second option, which is:或者使用模板:
template<typename T>
void setRxHandler(void (T::*h)(int)) { ... }使用模板选项,您实际上无法控制与setRxHandler (不包括RTTI)一起使用哪个类,这正是您想要的。
发布于 2011-07-30 17:01:23
C++不支持定界方法。要通过函数指针调用成员函数,需要有两件事:类的实例和函数指针。
所以setRxHandler(void (Y::*h)(int))几乎是正确的。你必须宣布它为:
void setRxHandler(Y*, void (Y::*h)(int));要调用setRxHandler(),需要按以下方式传递它的参数:
Y y;
setRxHandler(&y, &Y::comm_rxHandler);在setRxHandler()方法中,可以使用以下语法调用函数指针:
void setRxHandler ( Y* y, void (Y::*h)(int) )
{
// ...
(y->*h)(0);
// ...
}要使泛型化,您需要将Y参数抽象出去,但这很难实现。查看Boost.Function以获得支持此用例的现有实现,以及更多的实现。
发布于 2011-07-30 17:03:07
将回调更改为:
void setRxHandler(std::function(<void(int)>);然后,您可以使用绑定:
setRxHandler( std::bind(&class_name::comm_rxHandler, obj) );(std::function和std::bind是新版本的C++标准的一部分。很可能您的编译器已经与它们一起出现了。如果没有,它们可能生活在命名空间std::tr1中。如果其他一切都失败了,你会在助推 (他们发明的地方-- boost::function和boost::bind)找到它们。
但是,您也可以将非成员函数或静态函数传递给setRxHandler,以及函数对象(这是std::bind的结果)。
如果您的编译器已经支持lambda函数(也是下一个标准的一部分,但已经得到了GCC和VC的最新版本的支持),那么您也可以使用其中之一:
setRxHandler( [](){obj.comm_rxHandler();} );https://stackoverflow.com/questions/6884584
复制相似问题