[英]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()
本身是由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));
現在,當您要處理信號時,您真正想做的事情要復雜一些。 請記住,信號處理程序只能調用某些函數( 異步信號安全函數 ),否則可能會變得很丑陋。 因此,您應該執行一個常見的技巧,即自管技巧。 本質上,您應該有一個接收信號的信號處理程序,但只能在管道上以信號號作為要發送的數據調用write
。 然后,您在代碼中還有另一個地方需要調用管道上的select
,然后read
以讀取信號編號。 然后,您調用適當的處理程序函數,然后該函數便可以執行您喜歡的任何事情。
例如: http : //man7.org/tlpi/code/online/book/altio/self_pipe.c.html
請注意,以跨平台的方式實現此目標可能會有些棘手,尤其是在多線程的情況下。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.