Boost.Asio를 사용하여 C++ 11에서 서버 응용 프로그램을 만들고 있습니다. 저는 새로운 연결을 수락하는 클래스를 만들었습니다. Server
. 그것은 기본적으로 그냥 : 나는 두 가지 방법을 발견했습니다콜백의 장단점 (std :: function/std :: bind) vs 인터페이스 (추상 클래스)
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
주석, 즉 (I보다가 확신). 내 경우에는 Server
인스턴스를 소유 한 클래스 인스턴스로 다시 전달하기 만하면됩니다 (이 인스턴스는 Connection
클래스로 래핑 된 후 목록에 삽입됩니다). HandleAccept
에서라고 std::function<void(socket)> OnAccept
:
Server
는 생성자의 매개 변수가 있습니다.- 추상 클래스 인
IServerHandler
을 만들거나 하나의 가상 메서드OnAccept
을 만듭니다.Server
은 해당 생성자에서 매개 변수로IServerHandler
을 가져 오며 서버 인스턴스를 소유하는 클래스 인스턴스는IServerHandler
을 확장하고Server
을 구성하고*this
을 매개 변수로 사용합니다.
옵션 1과 옵션 2의 장단점은 무엇입니까? 더 좋은 옵션이 있습니까? 내 Connection
클래스 (OnConnectionClosed
)에서 동일한 문제가 발생합니다. 또한 시스템을 설계하는 방법에 따라 OnPacketReceived
및 OnPacketSent
콜백이 필요할 수 있습니다.
평생을 어떻게 관리하고 있습니까? 나는'weak_ptr>'이 좋은 콜백을 만든다는 것을 발견했다. (호출자는'shared_ptr'을 소유하고'.reset()'에 의해 그것을 제거한다). –
Yakk
'std :: function' 콜백을 변수로 사용하여'1'을 선호합니다. 그런 식으로'if (onData) onData (ptr, sz)'를 호출하기 전에 나중에 설정할 수 있습니다. – stefanB
하나의 특별한 경우 객체가 움직일 때 상속이 바람직합니다. 옮겨진 객체를 캡쳐 한 람다는 무효가되어 이동 생성자/할당은 목적지 객체에 대한 새로운 람다를 생성해야합니다. 상속은'this' 포인터의 유효성을 유지합니다. – DanielKO