尧图网站建设 尧图网络
  • 首页
  • 关于我们
  • 服务项目
  • 案例展示
  • 建站流程
  • 资讯中心
  • 联系我们
首页/资讯中心/详情

修改很简单,但网上讲这点的文档不多,因此多记一笔。另外基于out_ptr会临时转移所有权这点来看,共享所有权模型的std::shared_ptr其实并不适合使用out_ptr,虽然标准没有禁止甚至还要

修改很简单,但网上讲这点的文档不多,因此多记一笔。另外基于out_ptr会临时转移所有权这点来看,共享所有权模型的std::shared_ptr其实并不适合使用out_ptr,虽然标准没有禁止甚至还要
📅 发布时间:2026/7/1 2:36:22

inout_ptr的名字比较抽象,但只是在out_ptr的基础上加了个“in”而已。它会返回一个std::inout_ptr_t类型的对象,函数签名如下:

#include <memory>
template< class Pointer = void, class Smart, class... Args >
auto inout_ptr( Smart& s, Args&&... args );

这个“in”是指使用output parameter的函数在重新设置参数的值之前会先使用他们,因此这些函数的特点是:

  1. 非常在乎output parameter里有什么值,根据这些值执行不同的操作
  2. 函数调用期间完全享有output parameter和其资源的所有权
  3. 函数返回后output parameter不变或者被设置为新值

还是看例子,我们对Data增加一个update_data函数,如果name是recreate则删除原来的对象重新创建一个:

int update_data(Data **data)
{
if (data == nullptr || *data == nullptr)
return 1;
if ((*data)->name == "recreate") {
delete *data;
*data = new Data{"apocelipes"};
return 2; // 代表已修改
}
return 0;
}

现实中没人这么写代码,但存在很多类似的c接口,而且我们也很难控制第三方库的代码质量,难免不会遇上类似的东西。如果想在这种接口上用智能指针,那只能说有福了:

auto resource = std::make_unique<Data>("recreate");
Data *ptr = resource.get();
resource.release(); // 释放所有权,但不释放资源
if (auto code = update_data(&ptr); code == 1)
std::cerr << "error\n";
else if (code == 2) {
resource.reset(ptr);
std::cout << "updated, name: " << resource->name << "\n";
} else {
resource.reset(ptr);
std::cout << "updated, name: " << resource->name << "\n";
}

可以看到代码会变得很复杂,而且一但忘记使用reset就会内存错误。这时候我们就需要inout_ptr帮忙了。

inout_ptr整体上和out_ptr差不多,都是让出资源的所有权然后重新把函数返回的值设置回去,但还有几个差异:

  1. 前面说过需要inout_ptr的函数是需要参数的值的,因此构造inout_ptr_t时之后放弃资源的所有权,不会像out_ptr那样释放资源本身
  2. 资源的释放是调用的函数的责任,inout_ptr只会把函数返回出来的值重新设置回智能指针

用inout_ptr改写后的代码如下:

auto resource = std::make_unique<Data>("recreate");
if (auto code = update_data(std::inout_ptr(resource)); code == 1)
std::cerr << "error\n";
else if (code == 2) {
std::cout << "updated, name: " << resource->name << "\n";
} else {
std::cout << "updated, name: " << resource->name << "\n";
}

代码看起来清爽多了。

另外虽然inout_ptr也有变长参数,但标准明确规定它不能配合std::shared_ptr使用,这些参数std::unique_ptr用不上,是预留给其他的第三方的类似指针对象使用的。

注意事项

除了std::shared_ptr配合out_ptr使用时需要传入deleter,还有一个注意事项。

两个适配器都不建议这么用:

auto out = std::out_ptr(resource);
func(out);

因为他们都是在析构函数里重新设置智能指针的值,如果绑定到一个局部变量或者其他存储器的变量上,函数调用结束就无法把正确的值重新设置回智能指针,这会导致严重的内存错误。

唯一建议的用法是直接使用out_ptr和inout_ptr的返回值:func(std::out_ptr(resource)),这样函数调用结束后表达式结束,返回值作为表达式中创建的临时变量会被析构,这样智能指针的值就被正常设置了。

尽管只要在转换操作符上加上一点限制就能避免误用,但标准考虑到了各种边缘情形,最终没有添加限制,所以我们只能牢记这条注意事项避免踩坑了。

相关新闻

  • 【课程设计/毕业设计】基于 SpringBoot 的农业设备销售订单管理系统的设计与实现 基于 SpringBoot 的智慧农机综合服务管理系统【附源码、数据库、万字文档】
  • 【Springboot毕设全套源码+文档】基于Java+springboot电缆行业生产管理系统的设计与实现(丰富项目+远程调试+讲解+定制)
  • tqdm进度条:让命令行程序更友好

最新新闻

  • 如何保护您的 Reddit 账户:2026 年全方位安全运行Reddit账户
  • 什么是酒吧大屏互动系统?软硬件、功能模块、营收能力一文详解
  • 通俗易懂!三种解法彻底吃透【轮转数组】(LeetCode189)
  • PC+移动端双端测试:功能、兼容、一致性+排期
  • 智慧校园技术改造实战:智能锁身份核验+通断电联动,解决校园安全与运维痛点
  • 快上车!掌握多尺度Mamba新方法,快人一步发文章

日新闻

  • 2026年6月公司网站搭建最新热门渠道测评:四大低成本/零代码平台对比+避坑
  • 【Linux】Linux arm 编译QT程序,出现expected “}“报错
  • 【MATLAB例程】四基站二维AOA定位与距离辅助增强对比仿真。基于角度观测和测距修正的固定目标平面定位精度分析

周新闻

  • Windows字体自定义终极方案:No!! MeiryoUI完全指南
  • Deepin Boot Maker:告别命令行,3分钟制作Linux启动盘的智能解决方案
  • Plain Craft Launcher 2:重新定义你的Minecraft游戏体验

月新闻

  • 2026年6月公司网站搭建最新热门渠道测评:四大低成本/零代码平台对比+避坑
  • 【Linux】Linux arm 编译QT程序,出现expected “}“报错
  • 【MATLAB例程】四基站二维AOA定位与距离辅助增强对比仿真。基于角度观测和测距修正的固定目标平面定位精度分析

关于尧图

  • 公司简介
  • 团队介绍
  • 企业文化
  • 荣誉资质

服务项目

  • 定制开发
  • 电商建站
  • UI 设计
  • 运维服务

快速链接

  • 案例展示
  • 建站流程
  • 常见问题
  • 资讯中心

联系方式

  • 📍北京市朝阳区互联网产业园 A 座 10 层
  • 📞400-888-8888
  • ✉️contact@rkmt.cn
  • 🕐周一至周日 9:00-21:00

© 2024 北京尧图网络科技有限公司 版权所有 | 京 ICP 备 XXXXXXXX 号