栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

【C++】智能指针shared

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

【C++】智能指针shared

智能指针

C++中动态内存由new/delete,new []/delete []来进行管理,需要编程人员确保在正确的时机释放已经使用结束的动态内存,容易产生内存泄漏或在释放内存后仍继续使用指针导致非法访问,于是C++11提供了智能指针来管理动态对象。

  • shared_ptr
  • unique_ptr
  • weak_ptr
shared_ptr

shared_ptr允许多个指针指向同个对象,使用方式和普通指针类似,解引用智能指针来得到指向的对象

shared_ptrp1;

最安全的分配和使用方式就是调用make_shared函数,在动态内存中分配一个对象并初始化,返回指向此对象的shared_ptr

shared_ptrp1=make_shared(1);//指向值为1的整型数据
shared_ptrp2=make_shared(3,'a');//指向值为aaa的字符串数据

也可以使用new来初始化智能指针,但是只能指针构造函数是explicit的,不接受隐式转换,必须使用直接初始化智能指针

shared_ptrp1=new int(1024);//错误,无法使用隐式转换int* -> shared_ptr
shared_ptrp2(new int(1024));//正确,使用直接初始化智能指针
shared_ptrclone(int p){
	return new int(p);//错误,无法使用隐式转换
}
shared_ptrclone(int p){
	return shared_ptr(new int(p));//正确,显式创建shared_ptr
}

当进行拷贝或赋值操作,shared_ptr有引用计数,当计数器变为0,自动调用对象的析构函数,释放所管理的对象

auto p1=make_shared(1);
auto p2=make_shared(2);
auto q(p);//计数器加1
p1=q;//p1原来的对象计数器为0,释放对象

一般使用动态内存出于以下三种原因:

  1. 程序不知道自己需要使用多少对象
  2. 程序不知道所需对象的准确类型
  3. 程序需要在多个对象间共享数据

为了正确使用智能指针,需要坚持基本规范:

  1. 不使用相同的内置指针值初始化或reset多个智能指针
  2. 不delete由get()返回的指针
  3. 不使用get()初始化或reset另一个智能指针
  4. 使用了get()返回的指针,当最后一个对应的智能指针被销毁后,该指针变为空悬指针
  5. 如果智能指针管理的资源不是new分配的内存,需要传递一个删除器
unique_ptr

unique_ptr拥有它指向的对象。与shared_ptr不同,某个时刻只能有一个unique_ptr指向一个给定对象。当unique_ptr被销毁时,它所指向的独享也被销毁。
unique_ptr没有类似make_shared的标准库函数返回一个unique_ptr。当我们定义一个unique_ptr时,需要将其绑定到一个new返回的指针上。类似shared_ptr,初始化unique_ptr必须采用直接初始化形式:

unique_ptrp1;//可以指向一个double的unique_ptr
unique_ptrp2(new int(42));//p2指向一个值为42的int

由于一个unique_ptr拥有指向它指向的对象,因此unique_ptr不支持普通的拷贝或赋值操作:

unique_ptrp1(new string("helloworld"));
unique_ptrp2(p1);//错误,unique_ptr不支持拷贝
unique_ptrp3;
p3=p2;//错误,unique_ptr不支持赋值

不能拷贝或赋值unique_ptr,但是可以通过调用release或reset将指针的所有权从unique_ptr转移给另一个unique_ptr:

unique_ptrp2(p1.release());//release将p1置空,p2绑定到返回指针
unique_ptrp3(new string("hello"));
p2.reset(p3.release());//reset释放了p2原来指向的内存指向p3.release返回的指针

release成员返回unique_ptr当前保存的指针并将其置为空。因此p2被初始化为p1原来保存的指针,p1被置为空。
reset成员接受一个可选的指针参数,令unique_ptr重新指向给定的指针。因此p2调用reset释放了内存,将p3对指针的所有权转移给p2,并将p3置为空。
调用release会切断unique_ptr和它原来管理的对象间的联系。release返回的指针通常被用来初始化另一个智能指针或给另一个智能指针赋值。但是如果我们不用另一个智能指针来保存release返回的指针,我们的程序就要负责资源的释放:

p2.release();//错误,p2不会释放内存,而且丢失了指针
auto p = p2.release();//正确,记得delete(p);
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/960856.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号