简体   繁体   English

从另一个方法调用成员方法指针

[英]Invoking a member method pointer from another method

In class Foo I have two methods, assign_handler() and call_handler() . class Foo我有两种方法, assign_handler()call_handler()

The actual handler code is in the main.cpp which is do_this() . 实际的处理程序代码在main.cpp ,该代码为do_this() do_this() uses the some global variables in main.cpp , do_this()使用main.cpp的一些全局变量,

I think Foo has to have a function pointer as member which will be assigned in assign_handler() which is what I did. 我认为Foo必须具有一个函数指针作为成员,这将在我做的assign_handler()分配。 However I'm having trouble invoking assign_handler() ie calling do_this() , from call_handler() . 但是我在调​​用assign_handler()遇到麻烦,即调用do_this() ,即调用do_this() call_handler()

Note: call_handler() itself is call by a sigaction in Foo . 注意: call_handler()本身是由Foosigaction调用的。

EDIT: I tried producing a MCVE as suggested in the comments. 编辑:我尝试按照注释中的建议生成MCVE。 I've used gedit to create the files and compile it using g++ in command line. 我已经使用gedit创建文件并在命令行中使用g ++对其进行编译。 The code works. 该代码有效。 However in my Eclipse project I get the errors shown in inline comments of the code. 但是,在我的Eclipse项目中,我得到了代码内联注释中显示的错误。

MCVE: MCVE:

//Foo.h
class Foo{
public:
    void (*funptr)(void);
    void call_handler();
    void assign_handler (void(*func1)(void));
    Foo(){};

};
//Foo.cpp
#include "Foo.h"
void Foo::assign_handler(void(*func1)(void)){
    funptr = func1;
}
void Foo::call_handler(){
    funptr();//error: invalid use of member Foo::funptr in static member function; from this location
    //or
    //this->funptr();//error: 'this' is unavailable for static member functions
}
//main.cpp
#include <iostream>
#include "Foo.h"
using namespace std;
void do_this(void);
int main(void){
    Foo foo;
    foo.assign_handler(do_this);

    foo.call_handler(); //this won't be called explicitly, it is assigned as a handler for a sigaction
    int x;
    cin>>x;
}

void do_this(void){
    cout<<"done"<<endl;
}

I'll divide my answer in two parts. 我将答案分为两部分。 First I'll attempt to answer your question, then I'll attempt to tell you what you actually want to do. 首先,我将尝试回答您的问题,然后尝试告诉您您实际要做什么。

Your question is how to assign a function pointer to a member variable and then call it from a static member function. 您的问题是如何将函数指针分配给成员变量,然后从静态成员函数中调用它。 Since the function pointer is a member of the class you will also require a pointer to the class in order to call the function pointer. 由于函数指针是该类的成员,因此您还需要一个指向该类的指针才能调用该函数指针。 A way of achieving this is to add a static member to your class that holds a pointer to the (single) instance of your class. 实现此目的的一种方法是向您的类中添加一个静态成员,该成员包含指向您的类(单个)实例的指针。 Since you indicated that you will be using this as a signal handler, you won't want to use multiple handlers anyway. 由于您已指示将其用作信号处理程序,因此无论如何您都不想使用多个处理程序。

So, something like this: 因此,如下所示:

//Foo.h
class Foo{
public:
    static void call_handler();
    void assign_handler (void(*func1)(void));

    Foo() {    
       ms_instance = this;
    };

private:
    void (*funptr)(void);
    static Foo *ms_instance;
};

//Foo.cpp
#include "Foo.h"
void Foo::assign_handler(void(*func1)(void)){
    funptr = func1;
}
void Foo::call_handler(){
    ms_instance->funptr();
}

A more general way would be to store a function object: 一个更通用的方法是存储一个函数对象:

//Foo.h
#include <functional>
#include <utility>

class Foo{
public:
    static void call_handler();

    template<typename func>
    void assign_handler (func&& handler)
    {
        m_handler = std::forward(handler);
    }

    Foo() {
       ms_instance = this;
    };

private:
    std::function<void(void)> m_handler;
    static Foo *ms_instance;
};

//Foo.cpp
#include "Foo.h"

void Foo::call_handler(){
    ms_instance->m_handler();
}

This way you can assign lots of different stuff as the handler: 这样,您可以分配许多不同的内容作为处理程序:

// Function pointers
foo.assign_handler(do_this);

// Lambdas
foo.assign_handler([]() { /* do something */ });

// Binds - you should probably prefer lambdas...
foo.assign_handler(std::bind(&MyClass::member_func, &myObj));

Now what you actually want to do when you are going to handle a signal is a bit more complicated. 现在,当您要处理信号时,您真正想做的事情要复杂一些。 Remember that signal handlers can only call certain functions ( async-signal-safe functions ) - otherwise things may get ugly. 请记住,信号处理程序只能调用某些函数( 异步信号安全函数 ),否则可能会变得很丑陋。 Therefore there is a common trick that you should perform called the self pipe trick. 因此,您应该执行一个常见的技巧,即自管技巧。 Essentially you should have a signal handler that receives the signal, but only calls write on a pipe with the signal number as the data to send. 本质上,您应该有一个接收信号的信号处理程序,但只能在管道上以信号号作为要发送的数据调用write Then you have another place in your code that calls select on the pipe and then read to read the signal number. 然后,您在代码中还有另一个地方需要调用管道上的select ,然后read以读取信号编号。 You then call the appropriate handler function which is then allowed to do whatever you like. 然后,您调用适当的处理程序函数,然后该函数便可以执行您喜欢的任何事情。

An example of this is here: http://man7.org/tlpi/code/online/book/altio/self_pipe.c.html 例如: http//man7.org/tlpi/code/online/book/altio/self_pipe.c.html

Be aware that it can be slightly tricky to get this right in a cross-platform manner, especially if multithreaded. 请注意,以跨平台的方式实现此目标可能会有些棘手,尤其是在多线程的情况下。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM