无法调用结构内部的成员函数指针

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了无法调用结构内部的成员函数指针相关的知识,希望对你有一定的参考价值。

在我的程序中声明,定义并最终调用成员函数指针时,我一直在努力学习语法。

我正在用Xlib编写一个窗口管理器,并且我试图让用户在Keybinds的向量中定义所有键绑定。 Keybind结构包含更多成员变量,为了简洁起见,我在此留下了这些变量。

这是我到目前为止所得到的。

Keybind,一个包含成员变量func的结构,指向MyClass成员函数。

struct MyBind {
    MyBind(void (MyClass::*_func)(const XKeyEvent&))
    : func(_func) {}

    void (MyClass::*func)(const XKeyEvent&);
}

声明和填充持有用户定义的vectors的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 scopeg++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关键字,您希望调用MyClassfunc实例。

以上是关于无法调用结构内部的成员函数指针的主要内容,如果未能解决你的问题,请参考以下文章

this指针 (保存调用成员函数对象的地址)

如何调用成员函数指针?

是否可以修改函数内部结构指针的内容?

调用成员函数指针

将取消引用的指针作为函数参数传递给结构

类的内存结构