news 2026/7/2 1:59:08

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

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
现实中没人这么写代码,但存在很多类似的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差不多,都是让出资源的所有权然后重新把函数返回的值设置回去,但还有几个差异:

前面说过需要inout_ptr的函数是需要参数的值的,因此构造inout_ptr_t时之后放弃资源的所有权,不会像out_ptr那样释放资源本身
资源的释放是调用的函数的责任,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)),这样函数调用结束后表达式结束,返回值作为表达式中创建的临时变量会被析构,这样智能指针的值就被正常设置了。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/2 1:58:49

OpenHarmony 英语学习 App 实战:基于艾宾浩斯曲线的单词复习系统设计

OpenHarmony 英语学习 App 实战&#xff1a;基于艾宾浩斯曲线的单词复习系统设计 摘要 背单词最难的不是“第一次记住”&#xff0c;而是“过几天还记得”。所以英语学习 App 不能只做词汇列表&#xff0c;还需要一套复习调度系统。本文以「英语视界 YingYu」项目为例&#xff…

作者头像 李华
网站建设 2026/7/2 1:56:51

记录:2026.7.1

写了三道分块的紫&#xff08;上午、下午、晚上各一道&#xff09; 写了三篇优质题解&#xff0c;极其优值&#xff01;

作者头像 李华
网站建设 2026/7/2 1:55:08

深度学习核心架构与工业部署实战指南

1. 深度学习的前世今生2006年&#xff0c;多伦多大学教授Geoffrey Hinton在《Science》上发表的那篇开创性论文&#xff0c;就像一颗火星点燃了整个机器学习领域的草原。当时还在读研的我&#xff0c;第一次在实验室看到师兄跑通的MNIST手写数字识别demo时&#xff0c;那种震撼…

作者头像 李华
网站建设 2026/7/2 1:53:33

第93题 IGBT模块陶瓷基板(AlN/Al₂O₃/Si₃N₄)金属化

2026年国家级科研痛点&#xff1a;IGBT模块陶瓷基板&#xff08;AlN/Al₂O₃/Si₃N₄&#xff09;金属化 痛点直陈 IGBT模块陶瓷基板金属化这道工序&#xff0c;卡着国产高端功率模块的脖子。氧化铝&#xff08;Al₂O₃&#xff09; 便宜、工艺成熟&#xff0c;但导热率只有24 …

作者头像 李华
网站建设 2026/7/2 1:52:24

基于 IOCP 的协程调度器——零基础深入浅出 C++20 协程

基于完成端口的 IO 多路复用上文中提到了 Unix 系统中多路复用接口的发展历程&#xff1a;分别经历了 select -> poll -> epoll/kqueue&#xff0c;Windows 则通过完成端口一统江山&#xff0c;其实它俩调用方式差不太多&#xff1a;epollIOCP初始化epoll_createCreateIo…

作者头像 李华