我的目的是设计网络通信中的事件回调模型,该事件回调包括“ recv,发送,接受,关闭...”
class client
{
public:
template<typename F1>
void bind_recv(F1 && f)
{
// How to save the parameter of bind_recv function in _recv_callback member variable ?
_recv_callback = f;
}
// bind_send
// bind_accept
// bind_shutdown
// ...
protected:
void notify_recv()
{
_recv_callback();
}
// notify_send
// ...
// How to declare the type of these variable ?
F1 _recv_callback;
// F2 _send_callback;
// ...
};
int main()
{
client c;
c.bind_recv([](uint8_t * data, size_t len)
{
});
return(0);
}
我需要保存回调并在正确的时间调用它们,但是每个回调函数的参数都不同,那么如何保存它们?
我想也许我的想法是错误的,那么如何更改设计以满足这一要求?
答案 0 :(得分:0)
您不能声明模板成员变量。但是,即使可以使用模板类型_recv_callback
声明F1
,也必须在编译时确定F1
。那么client::bind_recv
_recv_callback = f;
当传递的参数f
的类型不是_recv_callback
时
即使您能够为_recv_callback
定义一个赋值运算符,该赋值运算符在右侧允许使用不同的类型,也可以“丢失”一些信息。具体来说,分配后,您将不再知道f
的类型。更糟糕的是,f
可能有一些额外的成员变量,您无法存储在_recv_callback
中。
解决这些问题的方法是,首先定义要传递给f
的允许参数client::bind_recv
的通用“基”(可能是抽象)类。然后,您可以使用多态来处理不同的情况。示例:
#include <memory>
class callback {
// Some purely virtual functions for a generic interface
virtual ~callback { }
};
class recv_callback : callback {
// Specific implementations of pure virtual members declared in callback
virtual recv_callback;
};
class client
{
public:
void bind_recv(callback *f)
{
_recv_callback.reset(f);
}
protected:
std::unique_ptr<callback> _recv_callback;
}
通过传递指向client::bind_recv
的指针,可以避免不知道如何处理未知类型的f
的问题:您需要传递已经分配的对象。
另外,请注意,我为_recv_callback
使用了智能指针,以确保不会泄漏内存。