在我的程序中声明,定义并最终调用成员函数指针时,我一直在努力学习语法。
我正在用Xlib编写一个窗口管理器,并且我试图让用户在Keybind
s的向量中定义所有键绑定。 Keybind
结构包含更多成员变量,为了简洁起见,我在此留下了这些变量。
这是我到目前为止所得到的。
Keybind
,一个包含成员变量func
的结构,指向MyClass
成员函数。
struct MyBind {
MyBind(void (MyClass::*_func)(const XKeyEvent&))
: func(_func) {}
void (MyClass::*func)(const XKeyEvent&);
}
声明和填充持有用户定义的vector
s的Keybind
。
// in my_class.hh
std::vector<MyBind*> my_binds_;
// in my_class.cc, constructor
my_binds_.push_back(new MyBind( &MyClass::do_this ));
my_binds_.push_back(new MyBind( &MyClass::do_that ));
在这一点上,一切都编译并运行。
现在,当我尝试通过迭代my_binds_
向量来委托工作时,事情就出错了。值得注意的是,为了清楚起见,我省略了错误处理和其他成员变量访问。
void
MyClass::handle_input(const XKeyEvent& e)
{
for (const MyBind* my_bind: my_binds_) {
(my_bind->*func)(e); // erroneous line
}
}
这个should be the correct syntax,但它无法编译,说明error: ‘func’ was not declared in this scope
(g++
,clang++
类似的错误)。
这对我来说很奇怪,因为用auto test = keybind->func;
替换错误的代码行会编译。
我究竟做错了什么?有没有更好的方法来处理用户密钥绑定定义?谢谢!
最好使用std::function并完全忘记原始成员函数指针。他们只会给你带来痛苦:)
您的代码问题是您只有一个指向方法但没有对象的指针。你的bind结构也应该存储一个对象指针来调用方法:
struct MyBind {
MyBind(MyClass *obj, void (MyClass::*_func)(const XKeyEvent&))
: obj(obj), func(_func) {}
MyClass *obj;
void (MyClass::*func)(const XKeyEvent&);
void operator()(const XKeyEvent& event) const
{
(obj->*func)(event);
}
}
然后像这样使用它:
void
MyClass::handle_input(const XKeyEvent& e)
{
for (const MyBind* my_bind: my_binds_) {
(*my_bind)();
}
}
为方便起见,我在bind结构中添加了一个调用操作符。请注意,->*
运算符应用于方法所属的对象。
为什么不使用标准库。即就像是:
#include <algorithm>
#include <functional>
...
typedef std::function<void(const XKeyEvent&)> key_event_handler;
std::vector< key_event_handler > my_binds_;
....
MyClass::MyClass() {
my_binds_.push_back( std::bind(&MyClass::do_this, this, std::placeholders::_1) );
my_binds_.push_back( std::bind(&MyClass::do_that, this, std::placeholders::_1) );
}
....
void MyClass::handle_input(const XKeyEvent& e)
{
std::for_each(my_binds_.begin(), my_binds_.end(), [e] (key_event_handler& hndlr) {
hndlr( e );
} );
}
除了你可以看看boost signals2
这不是答案,而是指向你的答案的指针或我的问题:)
你必须使用
(this->*(my_bind->func))(e);
代替:
(my_bind->*func)(e);
我重新创建了你的错误信息,并在经过多次尝试后问了一个问题。
看到这个(指向你答案的指针;)):How to call pointer to member function, which has been saved in a vector of custom struct?
MyBind
持有指向MyClass
某个实例的成员函数的指针。因此,为了调用这些函数指针,您需要明确告诉使用this
关键字,您希望调用MyClass
的func
实例。