Я создаю серверное приложение на С++ 11 с помощью Boost.Asio. Я создал класс 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();
}
Я нашел два способа (я уверен, что их больше), чтобы "исправить" комментарий TODO, т.е. переместить сокет туда, куда он должен идти. В моем случае я просто хочу вернуться к экземпляру класса, которому принадлежит экземпляр Server (который затем переносит его в класс Connection и вставляет его в список).
-
Serverимеет параметр в своем конструкторе:std::function<void(socket)> OnAccept, который вызывается вHandleAccept. - Я создаю абстрактный класс
IServerHandlerили что угодно, у которого есть один виртуальный методOnAccept.ServerпринимаетIServerHandlerкак параметр в своем конструкторе, а экземпляр класса, владеющий экземпляром сервера, расширяетIServerHandlerи строитServerс параметром*this.
Каковы плюсы и минусы варианта 1 по сравнению с вариантом 2? Есть ли лучшие варианты? У меня такая же проблема в классе Connection (OnConnectionClosed). Кроме того, в зависимости от того, как я решаю создать систему, может потребоваться обратный вызов OnPacketReceived и OnPacketSent.