You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

关于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:拆分多行的正确写法

你尝试的写法是错误的,核心问题如下:

  1. 在栈上创建的chat_session A会在lambda函数结束时被销毁,而std::make_shared创建的是另一个独立的副本,两个对象完全无关
  2. 普通栈对象不能用->调用成员函数,需用.,但这不是本质问题
  3. 你已经把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有两个核心重载:

  1. 用户预创建socket的版本:你需要提前创建tcp::socket对象并传给async_accept,accept完成后连接会关联到这个socket上
  2. Asio自动创建socket的版本:也就是示例采用的版本,无需用户提前创建socket,Asio会在内部生成socket对象,再通过handler参数传递给你

示例用第二种版本只是为了代码简洁,少写一行创建socket的代码,两种版本底层逻辑完全一致,都是完成TCP连接的accept操作,只是socket的创建时机和方式不同,你可以根据需求任选其一。


内容的提问来源于stack exchange,提问作者AbsolutZero

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 05:17:21