我想要一个可以将回调函数设置为成员函数指针的类。这意味着我需要存储函数的地址和对象实例的地址。该函数应具有正确的原型,并将值返回到回调期望的值。
我玩过std::mem_fn
and boost::bind
(使用Boost Signals2库),但是似乎我必须知道包含用于存储此信息的回调函数的类的类型。
似乎应该有一种方法可以存储一对void*
指向任何对象/功能的对,但这显然闻起来很有趣,失去了类型安全性,等等。
给定一个SomeClass
带有方法的类some_method
,我希望能够执行以下操作:
SomeClass obj;
some_other_class.set_callback(&SomeClass::some_method, &obj);
这就是我如何使用Boost实现此目的的方法。请注意,这使用了Boost信号,对于简单的回调似乎有些过分。而且,由于使用多个“时隙”连接到单个信号,因此存在使用“组合器”确定回调的返回值的信号问题。我只需要一个回调的支持。另请注意,这是一个完整的可编译程序:
#define _SCL_SECURE_NO_WARNINGS
#include <iostream>
#include <boost/bind.hpp>
#include <boost/signals2.hpp>
#include <string>
using namespace std;
struct MessageSource
{
boost::signals2::signal<void(const string &)> send_message;
typedef boost::signals2::signal<void(const string &)>::slot_type slot_type;
template<typename A, typename B>
boost::signals2::connection connect(A a, B b)
{
return send_message.connect(boost::bind(a, b, _1));
}
void send_msg(const string& msg)
{
send_message(msg);
}
};
struct Printer
{
void print(const string& msg) { std::cout << msg << std::endl; };
};
int main()
{
{
Printer p;
MessageSource s;
s.connect(&Printer::print, &p);
s.send_msg("test");
}
system("pause");
return 0;
}
我认为这里的魔力是事实,boost::bind()
它能够为第一个参数处理多种类型的事实。我只是不知道如何在不知道类型的情况下将其保留在某种私有字段中...
这是函子确实是正确解决方案的情况吗?似乎成员函数使用起来更方便了...
根据上面cdhowie的评论,我能够使用std::function
和提出以下解决方案std::bind
:
#include <iostream>
#include <string>
#include <functional>
using namespace std;
struct MessageSource
{
function<void(const string& msg)> _callback;
template<typename A, typename B>
void connect(A func_ptr, B obj_ptr)
{
_callback = bind(func_ptr, obj_ptr, placeholders::_1);
}
void send_msg(const string& msg)
{
if (_callback)
_callback(msg);
}
void disconnect()
{
_callback = nullptr;
}
};
struct Printer
{
void print(const string& msg) { std::cout << msg << std::endl; };
};
int main()
{
{
Printer p;
MessageSource s;
s.connect(&Printer::print, &p);
s.send_msg("test");
s.disconnect();
s.send_msg("test again");
}
system("pause");
return 0;
}
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句