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

C++-标准库 智能指针smart pointer

文章目录

  • 概述
  • shared_ptr使用

概述

指针让我们在域边界之外拥有reference语义,然而,确保“pointer的寿命”和“其所指对象的寿命”一致却是件棘手的事。
C++11提供两大类型智能指针:shared_ptr和unique_ptr。

  • shared_ptr实现共享式拥有的概念。多个shared_ptr指向同一个对象,当最后一个shared_ptr析构时,指向的对象也被释放,标准库还提供weak_ptr, bad_weak_ptr, enable_shared_from_this等辅助类。
  • unique_ptr实现独占式拥有的概念。保证同一时间内只有一个指针指向对象,你可以移交所有权。

shared_ptr使用

shared_ptr的目标就是在其所指的对象不再被需要后,自动释放与之相关的资源。
构造:

shared_ptr<string> pStr1(new string("abc"));
shared_ptr<string> pStr2 = make_shared<string>("abc");

其中模板参数类型是指针指向的数据类型。
接受单一指针的构造函数是explicit的,因此不能进行隐式转换

shared_ptr<string> pStr = new string("abc");  // ERROR
shared_ptr<string> pStr{new string("abc")};  // OK

你也可以先声明shared_ptr再赋值一个指针给它。

shared_ptr<string> pStr;
pStr.reset(new string("abc"));
pStr = new string("abc"); // ERROR

你可以像使用指针一样使用shared_pointer

pStr->replace(0, 1, "J);
(*pStr)[0] = 'N';  // 改变string第一个元素

容器总是为传入的元素创建属于容器自己的拷贝,因此当把同一个shared_ptr重复添加到vector中时,多个shared_ptr将指向同一个string对象,当最后一个shared_ptr销毁时,会对其指向的对象调用delete
然而对于array,我们应该调用的是delete[],而不是delete,因此创建一个指向array的shared_ptr是错误的

shared_ptr<int> p(new int[10]); // ERROR

我们在第二个参数指定deleter

shared_ptr<int> p(new int[10], [](int*p) { delete[] p; });
shared_ptr<int> p(new int[10], std::default_delete<int[]>()); // default_delete默认调用delete[]

C++17之前,只有unique_ptr支持数组类型的模板

unique_ptr<int[]> p(new int[10]); // 正确。并且能够正确调用delete[]
shared_ptr<int[]> p(new int[10]); // 编译错误

C++17之后,shared_ptr也支持数组类型的模板,并且也可以像原生数组一样取数组元素

shared_ptr<int[]> p(new int[10]); // C++17以后正确
p[0] = 0; // C++17之后正确
p->get()[1] = 1; // C++11不支持operator[]可使用此写法,与上述语句等价

注:本人在visual studio上使用shared_ptr<int[]> p(new int[10]);没有检测到内存泄漏,可能是vs进行了优化?

参考:

  1. https://stackoverflow.com/questions/13061979/can-you-make-a-stdshared-ptr-manage-an-array-allocated-with-new-t

http://www.mrgr.cn/news/12804.html

相关文章:

  • 端口号问题(开发)
  • 云微客短视频矩阵如何打造多元化的视频内容呢?
  • 交换机自动化巡检(H3C)
  • linux下一切皆文件,如何理解?
  • 谁说微生态研究都是结果描述?
  • 【区块链 + 司法存证】枢纽链:区块链司法存证平台 | FISCO BCOS应用案例
  • 怎么把mp4转换成mp3?5种转换方法教会你
  • 【架构设计】安全架构设计
  • 在idea中回滚到某节点并push到远程仓库
  • 系统编程-消息队列
  • 【STM32】FSMC
  • leetcode 560 和为k 的子数组
  • spring整合redis(常用数据类型操作)
  • [英语单词] quorum
  • 呼入的电话通过http接口转接(mod_cti基于FreeSWITCH)
  • 实现通用人工智能 (AGI) 面临的挑战
  • “北京地铁系统中人脸识别技术的安全与效率问题研究”
  • LLVM-MLIR 学习记录
  • 如何使用ssm实现视频点播系统设计与实现+vue
  • 利用Aspose.BarCode 在 C# 中创建微型二维码