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

标签 c++ function-pointers

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

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

我认为 Foo 必须有一个函数指针作为成员,它将在 assign_handler() 中分配,这就是我所做的。但是,我在调用 assign_handler() 时遇到问题,即从 call_handler() 调用 do_this()

注意:call_handler() 本身是由Foo 中的sigaction 调用的。

编辑:我尝试按照评论中的建议制作 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));

现在当您要处理信号时,您实际上想要做的事情有点复杂。请记住,信号处理程序只能调用某些函数(async-signal-safe functions)——否则事情可能会变得很糟糕。因此,您应该执行一个常见的技巧,称为自管道技巧。本质上,您应该有一个接收信号的信号处理程序,但仅在管道上调用 write 并将信号编号作为要发送的数据。然后,您的代码中还有另一个地方调用管道上的 select,然后调用 read 以读取信号编号。然后您调用适当的处理函数,然后允许它做任何您喜欢的事情。

这里有一个例子:http://man7.org/tlpi/code/online/book/altio/self_pipe.c.html

请注意,以跨平台的方式做到这一点可能会有些棘手,尤其是在多线程的情况下。

关于c++ - 从另一个方法调用成员方法指针,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35669221/

相关文章:

c++ - QT部署错误

c++ - 需要 cdecl 说明 : what is an "array 5?"

c++ - 带有函数指针参数的模板类

C++ - 将函数链接到触发器的有效且高效的方法

c++ - 指向函数的指针不起作用

c++ - 如何修复简单 C++ 函数中的无限循环?

c++ - 多线程插件架构中的共享单侧可变状态

c++ - 指针初始化 : When to assign NULL to the initialized pointer?

c++ - MFC 容器 CObList 的 STL 迭代器

c++ - 调用并初始化类的静态成员函数