繁体   English   中英

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

[英]Invoking a member method pointer from another method

class Foo我有两种方法, assign_handler()call_handler()

实际的处理程序代码在main.cpp ,该代码为do_this() do_this()使用main.cpp的一些全局变量,

我认为Foo必须具有一个函数指针作为成员,这将在我做的assign_handler()分配。 但是我在调​​用assign_handler()遇到麻烦,即调用do_this() ,即调用do_this() call_handler()

注意: call_handler()本身是由Foosigaction调用的。

编辑:我尝试按照注释中的建议生成MCVE。 我已经使用gedit创建文件并在命令行中使用g ++对其进行编译。 该代码有效。 但是,在我的Eclipse项目中,我得到了代码内联注释中显示的错误。

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;
}

我将答案分为两部分。 首先,我将尝试回答您的问题,然后尝试告诉您您实际要做什么。

您的问题是如何将函数指针分配给成员变量,然后从静态成员函数中调用它。 由于函数指针是该类的成员,因此您还需要一个指向该类的指针才能调用该函数指针。 实现此目的的一种方法是向您的类中添加一个静态成员,该成员包含指向您的类(单个)实例的指针。 由于您已指示将其用作信号处理程序,因此无论如何您都不想使用多个处理程序。

因此,如下所示:

//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();
}

一个更通用的方法是存储一个函数对象:

//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();
}

这样,您可以分配许多不同的内容作为处理程序:

// 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));

现在,当您要处理信号时,您真正想做的事情要复杂一些。 请记住,信号处理程序只能调用某些函数( 异步信号安全函数 ),否则可能会变得很丑陋。 因此,您应该执行一个常见的技巧,即自管技巧。 本质上,您应该有一个接收信号的信号处理程序,但只能在管道上以信号号作为要发送的数据调用write 然后,您在代码中还有另一个地方需要调用管道上的select ,然后read以读取信号编号。 然后,您调用适当的处理程序函数,然后该函数便可以执行您喜欢的任何事情。

例如: http//man7.org/tlpi/code/online/book/altio/self_pipe.c.html

请注意,以跨平台的方式实现此目标可能会有些棘手,尤其是在多线程的情况下。

暂无
暂无

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

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