关于boost::asio chat_server中shared_ptr与async_accept的技术疑问
Boost.Asio Chat Server async_accept 疑问解答
对目标代码行的理解确认
你对这行代码的理解是正确的:
std::make_shared<chat_session>(std::move(socket), room_)->start();
它确实会:
- 创建一个
std::shared_ptr<chat_session>(匿名实例) - 通过移动语义将 acceptor 生成的socket转移到新的
chat_session对象中 - 将
room_的引用传入chat_session的构造函数 - 立即通过这个shared_ptr调用
start()方法,启动会话的异步读写逻辑
问题1:拆分多行的正确写法
你尝试的写法是错误的,核心问题如下:
- 在栈上创建的
chat_session A会在lambda函数结束时被销毁,而std::make_shared创建的是另一个独立的副本,两个对象完全无关 - 普通栈对象不能用
->调用成员函数,需用.,但这不是本质问题 - 你已经把
socket移动给了栈对象A,make_shared复制的A里的socket已经是无效状态
正确的拆分写法要保证shared_ptr直接管理chat_session的生命周期,代码如下:
// 创建shared_ptr,同时构造chat_session,将socket移动到对象内 auto session_ptr = std::make_shared<chat_session>(std::move(socket), room_); // 通过shared_ptr调用start()方法 session_ptr->start();
这么做的关键原因是:chat_session内的异步操作(如async_read/async_write)需要对象持续存活,shared_ptr能保证所有异步操作完成前,对象不会被销毁,这也是Boost.Asio异步编程中常用的生命周期管理手段。
问题2:async_accept的两种重载版本
basic_socket_acceptor::async_accept有两个核心重载:
- 用户预创建socket的版本:你需要提前创建
tcp::socket对象并传给async_accept,accept完成后连接会关联到这个socket上 - Asio自动创建socket的版本:也就是示例采用的版本,无需用户提前创建socket,Asio会在内部生成socket对象,再通过handler参数传递给你
示例用第二种版本只是为了代码简洁,少写一行创建socket的代码,两种版本底层逻辑完全一致,都是完成TCP连接的accept操作,只是socket的创建时机和方式不同,你可以根据需求任选其一。
内容的提问来源于stack exchange,提问作者AbsolutZero
相关产品推荐
相关产品推荐

