当类类型未知时调用成员函数
Call member function when class type is not known
我想要一个类,它可以为指向成员函数的指针设置回调。这意味着我需要存储函数的地址和对象实例的地址。函数应该具有正确的原型,并返回回调所期望的值。
我已经尝试过std::mem_fn
和boost::bind
(使用Boost Signals2库),但似乎我必须知道包含回调函数的类的类型才能存储这些信息。
似乎应该有一种方法来存储一对指向任何对象/函数的void*
,但这显然闻起来很有趣,失去了类型安全性等。
给定一个具有方法some_method
的类SomeClass
,我希望能够执行以下操作:
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;
}
相关文章:
- 无法调用成员函数,尝试正确执行此操作仍然失败
- 在 transform() 中调用成员函数
- C++::在构造函数退出之前通过指针调用成员函数
- 为什么我可以通过野生指针调用成员函数
- 从 Qt 中的信号调用成员函数的问题
- 调用C++成员函数指针,而不知道哪个类
- 如何从嵌套在命名空间中的类调用成员函数?
- 无法在非成员函数中调用成员函数
- 为什么分配了 nullptr 的指针可以调用成员函数?
- 通过带有成员函数指针的 QHash 调用成员函数的正确方法
- 使用可变参数模板调用成员函数
- 调用成员对象的构造函数
- 有没有办法在没有括号的情况下在C++中调用成员的getter/setter?
- 如何调用成员初始化器列表中参考成员的构造函数
- 使用按引用调用时,不能在没有对象的情况下调用成员函数 const
- 如果绝对没有调用成员函数,是否允许使用不完整类型的向量?如果是这样,从什么时候开始
- 在另一个成员函数中调用成员函数时'int'之前的预期主表达式
- 为什么调用成员函数不调用该对象的 ODR-USE?
- 如何在模板参数中调用成员
- 是否可以使用 EXPECT_CALL 来验证模拟对象的构造函数是否在某些时候调用成员函数?