C++ 泛型成员函数指针帮助
嘿,我有一个关于普通成员函数指针的问题。我正试图实现类似于以下问题的目标 本质上,我希望能够注册一个成员函数指针,该指针接受一个泛型事件对象作为其具有特定事件类型(例如,KeyboardEvent)的参数。然后,在我的输入管理类中,我希望能够做到的是,每当用户点击一个键时,我就可以创建一个KeyboardEvent对象,其中包含一些关于按键的数据,并调用所有我用KeyboardEvent对象作为参数注册的KeyboardEvent类型的成员函数指针 我一直在玩boost bind和boost函数,它们似乎使我能够完成95%的任务,唯一的问题是我试图将所有成员函数指针存储在一个向量中,但它们都是不同类型的,所以我不能这样做。因此,当我第一次向我的事件处理系统注册该方法时,我将它们绑定到一个函数对象中,该系统希望我在执行过程中指定此时的所有参数。我不必在这一点上创建对象,因为这些对象是由将来的未知事件生成的C++ 泛型成员函数指针帮助,c++,generics,function-pointers,C++,Generics,Function Pointers,嘿,我有一个关于普通成员函数指针的问题。我正试图实现类似于以下问题的目标 本质上,我希望能够注册一个成员函数指针,该指针接受一个泛型事件对象作为其具有特定事件类型(例如,KeyboardEvent)的参数。然后,在我的输入管理类中,我希望能够做到的是,每当用户点击一个键时,我就可以创建一个KeyboardEvent对象,其中包含一些关于按键的数据,并调用所有我用KeyboardEvent对象作为参数注册的KeyboardEvent类型的成员函数指针 我一直在玩boost bind和boost函数
如果这些都没有意义,很抱歉。如果我正确理解您的问题,您可以尝试以下内容
// function pointer, function with similar signature can be cast as function_t
typedef int (*function_t)(object_t *event, ...);
std:: vector<function_t> function_pointers;
// populate vector, e.g. function_pointers.push_back((function_t)&some_function)
void handle_event(object_t *event) {
for (...) (function_pointers.at(i))(event, ...);
}
//函数指针,具有类似签名的函数可以转换为函数\u t
typedef int(*函数)(对象*事件,…);
std::向量函数_指针;
//填充向量,例如函数指针。向后推((函数)和某些函数)
无效句柄事件(对象事件){
对于(…)(函数_指针.at(i))(事件,…);
}
我重读了你的问题,终于抓住了成员函数部分。为此,可以使用函子
struct base {
virtual void function(event_t *event)= 0;
};
template<class A>
struct F : base {
F(A &a) : object_(a) {}
virtual void function(event_t *a) { object_.function(a); }
A &object_;
};
std:: vector<base*> callback_vector;
...
callback_vector.push_back(new F<event_handler>(event_handler_object));
struct base{
虚空函数(event_t*event)=0;
};
模板
结构F:base{
F(A&A):对象{(A){}
虚空函数(event_t*a){object_.function(a);}
A&object;
};
std::vector callback\u vector;
...
回调向量。推回(新的F(事件处理程序对象));
如果我正确理解您的问题,您可以尝试以下内容
// function pointer, function with similar signature can be cast as function_t
typedef int (*function_t)(object_t *event, ...);
std:: vector<function_t> function_pointers;
// populate vector, e.g. function_pointers.push_back((function_t)&some_function)
void handle_event(object_t *event) {
for (...) (function_pointers.at(i))(event, ...);
}
//函数指针,具有类似签名的函数可以转换为函数\u t
typedef int(*函数)(对象*事件,…);
std::向量函数_指针;
//填充向量,例如函数指针。向后推((函数)和某些函数)
无效句柄事件(对象事件){
对于(…)(函数_指针.at(i))(事件,…);
}
我重读了你的问题,终于抓住了成员函数部分。为此,可以使用函子
struct base {
virtual void function(event_t *event)= 0;
};
template<class A>
struct F : base {
F(A &a) : object_(a) {}
virtual void function(event_t *a) { object_.function(a); }
A &object_;
};
std:: vector<base*> callback_vector;
...
callback_vector.push_back(new F<event_handler>(event_handler_object));
struct base{
虚空函数(event_t*event)=0;
};
模板
结构F:base{
F(A&A):对象{(A){}
虚空函数(event_t*a){object_.function(a);}
A&object;
};
std::vector callback\u vector;
...
回调向量。推回(新的F(事件处理程序对象));
这并不是对你的问题的真正回答,只是一个暗示,表明你正在努力实现的目标已经存在
看起来您正在尝试实现观察者模式。你可以读到它。掌握了观察者模式后,请查看库。boost::signal
类似于事件处理程序函数指针的向量,但功能更强大
下面是使用Boost::Signals2检测输入字符的示例。希望能有帮助
#include <iostream>
#include <boost/signals2.hpp>
#include <boost/bind.hpp>
//-----------------------------------------------------------------------------
struct KeyboardEvent
{
char key;
};
//-----------------------------------------------------------------------------
class Keyboard
{
private:
typedef boost::signals2::signal<void (KeyboardEvent)> SignalType;
SignalType signal_;
public:
typedef SignalType::slot_type SlotType;
// Subscribes to keyboard events
boost::signals2::connection connect(const SlotType& slot)
{
return signal_.connect(slot);
}
// Scans for keyboard events and notifies subscribers
void scan()
{
KeyboardEvent event;
std::cin >> event.key;
signal_(event);
}
};
//-----------------------------------------------------------------------------
class KeyPrinter
{
private:
void onKey(KeyboardEvent event)
{
std::cout << "You hit \'" << event.key << "\'\n";
}
boost::signals2::connection connection_;
public:
void connect(Keyboard& keyb)
{
connection_ = keyb.connect(
boost::bind(&KeyPrinter::onKey, this, _1) );
}
void disconnect() {connection_.disconnect();}
};
//-----------------------------------------------------------------------------
class Quitter
{
private:
void onKey(KeyboardEvent event)
{
if (event.key == 'q' || event.key == 'Q') {quit_ = true;}
}
boost::signals2::connection connection_;
bool quit_;
public:
void connect(Keyboard& keyb)
{
quit_ = false;
connection_ = keyb.connect(
boost::bind(&Quitter::onKey, this, _1) );
}
void disconnect() {connection_.disconnect();}
bool quitDetected() {return quit_;}
};
//-----------------------------------------------------------------------------
int main()
{
Keyboard keyb;
KeyPrinter printer;
Quitter quitter;
printer.connect(keyb);
quitter.connect(keyb);
while (!quitter.quitDetected())
{
keyb.scan();
}
}
#包括
#包括
#包括
//-----------------------------------------------------------------------------
结构键盘事件
{
字符键;
};
//-----------------------------------------------------------------------------
类键盘
{
私人:
类型DEF增压::信号2::信号信号类型;
信号类型信号;
公众:
typedef SignalType::slot_type SlotType;
//订阅键盘事件
boost::signals2::连接连接(const SlotType和slot)
{
返回信号连接(槽);
}
//扫描键盘事件并通知订阅者
无效扫描()
{
键盘事件;
std::cin>>event.key;
信号(事件);
}
};
//-----------------------------------------------------------------------------
类键打印机
{
私人:
void onKey(键盘事件)
{
这并不是你问题的真正答案,只是暗示你正在努力完成的事情已经存在
您似乎正在尝试实现观察器模式。您可以了解它。一旦掌握了观察器模式,请查看库。boost::signal
就像事件处理程序函数指针的向量,但功能更强大
下面是一个使用Boost::Signals2检测输入字符的示例。希望对您有所帮助
#include <iostream>
#include <boost/signals2.hpp>
#include <boost/bind.hpp>
//-----------------------------------------------------------------------------
struct KeyboardEvent
{
char key;
};
//-----------------------------------------------------------------------------
class Keyboard
{
private:
typedef boost::signals2::signal<void (KeyboardEvent)> SignalType;
SignalType signal_;
public:
typedef SignalType::slot_type SlotType;
// Subscribes to keyboard events
boost::signals2::connection connect(const SlotType& slot)
{
return signal_.connect(slot);
}
// Scans for keyboard events and notifies subscribers
void scan()
{
KeyboardEvent event;
std::cin >> event.key;
signal_(event);
}
};
//-----------------------------------------------------------------------------
class KeyPrinter
{
private:
void onKey(KeyboardEvent event)
{
std::cout << "You hit \'" << event.key << "\'\n";
}
boost::signals2::connection connection_;
public:
void connect(Keyboard& keyb)
{
connection_ = keyb.connect(
boost::bind(&KeyPrinter::onKey, this, _1) );
}
void disconnect() {connection_.disconnect();}
};
//-----------------------------------------------------------------------------
class Quitter
{
private:
void onKey(KeyboardEvent event)
{
if (event.key == 'q' || event.key == 'Q') {quit_ = true;}
}
boost::signals2::connection connection_;
bool quit_;
public:
void connect(Keyboard& keyb)
{
quit_ = false;
connection_ = keyb.connect(
boost::bind(&Quitter::onKey, this, _1) );
}
void disconnect() {connection_.disconnect();}
bool quitDetected() {return quit_;}
};
//-----------------------------------------------------------------------------
int main()
{
Keyboard keyb;
KeyPrinter printer;
Quitter quitter;
printer.connect(keyb);
quitter.connect(keyb);
while (!quitter.quitDetected())
{
keyb.scan();
}
}
#包括
#包括
#包括
//-----------------------------------------------------------------------------
结构键盘事件
{
字符键;
};
//-----------------------------------------------------------------------------
类键盘
{
私人:
类型DEF增压::信号2::信号信号类型;
信号类型信号;
公众:
typedef SignalType::slot_type SlotType;
//订阅键盘事件
boost::signals2::连接连接(const SlotType和slot)
{
返回信号连接(槽);
}
//扫描键盘事件并通知订阅者
无效扫描()
{
键盘事件;
std::cin>>event.key;
信号(事件);
}
};
//-----------------------------------------------------------------------------
类键打印机
{
私人:
void onKey(键盘事件)
{
std::cout(这里是对boost::function/bind问题的更直接的回答,没有boost.Signals2的内容。)
在使用boost::bind时,似乎没有使用_1、_2等占位符。此示例说明了应如何使用它们:
struct KeyboardEvent { char key; };
typedef boost::function<void (KeyboardEvent)> KeyboardHandler;
struct Handler
{
void onKey(KeyboardEvent event) {std::cout << event.key;}
};
int main()
{
Handler handler1, handler2;
std::vector<KeyboardHandler> handlers;
handlers.push_back(boost::bind(&Handler::onKey, &handler1, _1));
handlers.push_back(boost::bind(&Handler::onKey, &handler2, _1));
KeyboardEvent event;
event.key = 'z';
handlers[0](event);
handlers[1](event);
}
struct KeyboardEvent{char key;};
typedef boost::函数键盘处理程序;