当前位置: 首页 > news >正文

【C++98 智能指针1 auto_ptr的原理及代码案例】已弃用!!

std::auto_ptr 是 C++98 引入的一个简单的独占所有权智能指针,但在 C++11 中已经被弃用(deprecated),并在 C++17 中被移除。这是因为 std::auto_ptr 在所有权转移时的行为(特别是通过赋值和复制操作)可能导致意外的结果和难以调试的问题。

原理

std::auto_ptr 的原理是基于独占所有权的模型。它管理一个指向动态分配对象的指针,并在 auto_ptr 对象销毁时自动删除该对象。然而,与 std::unique_ptr 不同的是,std::auto_ptr 在赋值时会自动转移所有权,即将旧 auto_ptr 的指针设置为 nullptr,并将新指针的所有权转移给左侧的 auto_ptr。这种语义可能导致意外的副作用,特别是当多个 auto_ptr 指向同一个对象时。

代码案例(注意:不推荐使用)

以下是一个使用 std::auto_ptr 的简单示例(注意,这个示例仅用于演示 auto_ptr 的基本用法,不推荐在实际代码中使用):

#include <iostream>  
#include <memory> // 包含 auto_ptr 的头文件(仅在 C++98/03 中有效)  class MyClass {  
public:  MyClass(int value) : value_(value) {}  ~MyClass() { std::cout << "MyClass destroyed with value: " << value_ << std::endl; }  void print() const { std::cout << "MyClass value: " << value_ << std::endl; }  private:  int value_;  
};  int main() {  std::auto_ptr<MyClass> ptr1(new MyClass(10)); // 分配并初始化  ptr1->print(); // 输出:MyClass value: 10  // 所有权转移给 ptr2,ptr1 现在指向 nullptr  std::auto_ptr<MyClass> ptr2 = ptr1; // 注意这里会改变 ptr1 的值  ptr2->print(); // 输出:MyClass value: 10  // ptr1 现在是 nullptr,不能通过它访问 MyClass 对象  // ptr1->print(); // 这会导致运行时错误  // 当 ptr2 离开作用域时,MyClass 对象会被自动删除  // 输出:MyClass destroyed with value: 10  return 0;  
}

替代方案

由于 std::auto_ptr 的问题,推荐使用 std::unique_ptr 来代替它。std::unique_ptr 提供了更明确和安全的所有权语义,并且支持自定义删除器,从而提供了更大的灵活性。

例如,上面的代码可以改写为使用 std::unique_ptr:
#include <iostream>  
#include <memory> // 包含 unique_ptr 的头文件  // ...(类定义保持不变)...  int main() {  std::unique_ptr<MyClass> ptr1(new MyClass(10)); // 分配并初始化  ptr1->print(); // 输出:MyClass value: 10  // 注意:不能直接将 ptr1 赋值给另一个 unique_ptr,因为 unique_ptr 不支持复制构造和赋值操作  // 正确的做法是使用 std::move 来转移所有权  std::unique_ptr<MyClass> ptr2 = std::move(ptr1); // 转移所有权给 ptr2,ptr1 现在为空  ptr2->print(); // 输出:MyClass value: 10  // ptr1 现在是空的,不能通过它访问 MyClass 对象  // ptr1->print(); // 这会导致编译时错误  // 当 ptr2 离开作用域时,MyClass 对象会被自动删除  // 输出:MyClass destroyed with value: 10  return 0;  
}

相关文章:

  • Maven简单介绍
  • 优化 Flutter 应用开发:探索 ViewModel 的威力
  • 网络流量轮廓
  • 安全宣传咨询日活动向媒体投稿记住这个投稿好方法
  • 基于python的PDF文件解析器汇总
  • NVIDIA新模型Nemotron-4:98%的训练数据是合成生成的,你敢信?
  • 文字炫酷祝福 含魔法代码
  • 小阿轩yx-Apache 网页优化
  • CCAA质量管理【学习笔记】​​ 备考知识点笔记(六)质量改进系统方法与工具
  • Docker|了解容器镜像层(2)
  • 使用ReentrantLock和ThreadPoolExecutor模拟抢课
  • dmhs同步因目的端表自增列报错解决方法
  • 串口触摸屏的键盘控制
  • 1Mysql复习题
  • 实体类status属性使用枚举类型的步骤
  • Google 是如何开发 Web 框架的
  • JS中 map, filter, some, every, forEach, for in, for of 用法总结
  • 【Linux系统编程】快速查找errno错误码信息
  • CSS实用技巧干货
  • es的写入过程
  • JavaScript 基本功--面试宝典
  • Laravel Telescope:优雅的应用调试工具
  • MyEclipse 8.0 GA 搭建 Struts2 + Spring2 + Hibernate3 (测试)
  • MySQL用户中的%到底包不包括localhost?
  • RxJS 实现摩斯密码(Morse) 【内附脑图】
  • 深入浅出Node.js
  • 学习笔记DL002:AI、机器学习、表示学习、深度学习,第一次大衰退
  • 原创:新手布局福音!微信小程序使用flex的一些基础样式属性(一)
  • 阿里云服务器购买完整流程
  • ​比特币大跌的 2 个原因
  • (¥1011)-(一千零一拾一元整)输出
  • (2022版)一套教程搞定k8s安装到实战 | RBAC
  • (poj1.3.2)1791(构造法模拟)
  • (Redis使用系列) Springboot 使用redis实现接口Api限流 十
  • (附源码)springboot 基于HTML5的个人网页的网站设计与实现 毕业设计 031623
  • (四)七种元启发算法(DBO、LO、SWO、COA、LSO、KOA、GRO)求解无人机路径规划MATLAB
  • (算法)Travel Information Center
  • (原創) 人會胖會瘦,都是自我要求的結果 (日記)
  • (原創) 如何讓IE7按第二次Ctrl + Tab時,回到原來的索引標籤? (Web) (IE) (OS) (Windows)...
  • (转)用.Net的File控件上传文件的解决方案
  • (轉貼)《OOD启思录》:61条面向对象设计的经验原则 (OO)
  • ***监测系统的构建(chkrootkit )
  • ./indexer: error while loading shared libraries: libmysqlclient.so.18: cannot open shared object fil
  • .NET C# 使用 SetWindowsHookEx 监听鼠标或键盘消息以及此方法的坑
  • .net web项目 调用webService
  • .net8.0与halcon编程环境构建
  • .NET设计模式(8):适配器模式(Adapter Pattern)
  • .net知识和学习方法系列(二十一)CLR-枚举
  • .stream().map与.stream().flatMap的使用
  • @AliasFor 使用
  • [ vulhub漏洞复现篇 ] Jetty WEB-INF 文件读取复现CVE-2021-34429
  • [AIGC] Nacos:一个简单 yet powerful 的配置中心和服务注册中心
  • [C++ 从入门到精通] 12.重载运算符、赋值运算符重载、析构函数
  • [Deep Learning] 神经网络基础
  • [git]git命令如何取消先前的配置