sim*_*mon 34 c++ interface callback boost-asio c++11
我正在使用Boost.Asio在C++ 11中创建服务器应用程序.我创建了一个类,Server
它负责接受新的连接.它基本上只是:
void Server::Accept() {
socket_.reset(new boost::asio::ip::tcp::socket(*io_service_));
acceptor_.async_accept(*socket_,
boost::bind(&Server::HandleAccept, this, boost::asio::placeholders::error));
}
void Server::HandleAccept(const boost::system::error_code& error) {
if (!error) {
// TODO
} else {
TRACE_ERROR("Server::HandleAccept: Error!");
}
Accept();
}
Run Code Online (Sandbox Code Playgroud)
我找到了两种方法(我确定还有更多)来"修复" TODO
注释,即将套接字移动到应该去的地方.在我的情况下,我只想将它返回到拥有该Server
实例的类实例(然后将其包装在一个Connection
类中并将其插入到列表中).
Server
在其构造函数中有一个参数:std::function<void(socket)> OnAccept
调用它HandleAccept
.IServerHandler
或者其他什么,它有一个虚方法OnAccept
.Server
需要IServerHandler
在其构造函数的参数和类拥有实例的服务器实例扩展IServerHandler
,构建Server
以*this
作为参数.选项1与选项2的优缺点是什么?还有更好的选择吗?我的Connection
班级(OnConnectionClosed
)中遇到了同样的问题.此外,根据我决定如何设计系统,它可能需要一个OnPacketReceived
和OnPacketSent
回调.
Man*_*726 45
我非常喜欢第一种方式,原因如下:
通过接口/类层次结构表示概念/功能使得代码库不那么通用,灵活,并且在将来更难以保持或扩展.这种设计对类型(实现所需功能的类型)施加了一系列要求,这使得将来很难进行修改,并且在系统更改时最容易失败(考虑在修改基类时会发生什么)这种类型的设计).
你所谓的回调方法只是鸭子打字的经典例子.服务器类只需要一个可调用的东西来实现所需的功能,仅此而已.不需要"您的类型必须耦合到此层次结构"条件,因此实现处理的类型是完全免费的.
另外,正如我所说,服务器只需要一个可调用的东西:它可以是具有预期功能签名的任何东西.这为用户在实现处理程序时提供了更大的自由度.可以是全局函数,绑定成员函数,函子等.
以标准库为例:
几乎所有标准库算法都基于迭代器范围.C++中没有iterator
接口.迭代器只是实现迭代器行为的任何类型(可解除引用,可比较等).迭代器类型是完全自由的,不同的和解耦的(未锁定到给定的类层次结构).
另一个例子可能是比较器:比较器是什么?只是具有布尔比较函数签名的任何东西,可调用的东西,它接受两个参数并返回一个布尔值,表示从特定比较条件的角度看两个输入值是否相等(小于,大于等) .没有Comparable
界面.
归档时间: |
|
查看次数: |
6061 次 |
最近记录: |