智能指针shared_ptr,unique_ptr,weak_ptr

在C++中,动态内存的管理是通过一对运算符来完成的: new,在动态内存中为对象分配空间并返回一个指向该对象的指针,我们可以选择对对象进行初始化: delete,接受一个动态对象的指针,销毁该对象,并释放与之关联的内存。

为了更容易(同时也更安全)地使用动态内存,新的标准库提供了两种智能指针(smapointer)类型来管理动态对象。智能指针的行为类似常规指针,重要的区别是它负责自动释放所指向的对象。新标准库提供的这两种智能指针的区别在于管理底层指针的方式:shared ptr允许多个指针指向同一个对象;unique_ptr 则“独占”所指向的对象

标准库还定义了一个名为weak ptr的伴随类,它是一种弱引用,指向shared ptr所管理的对象。这三种类型都定义在memory头文件中。

shared_ptr:

智能指针是模板,必须提供指针指向的类型,像vector一样,在尖括号内给出类型,后面是定义的智能指针的名字。默认初始化的智能指针保存空指针。

下表为shared_ptr和unique_ptr都支持的操作:

下表为shared_ptr独有的操作:

make_shared函数:

最安全的分配和使用动态内存的方法是调用make_shared的标准库函数。此函数在动态内存中分配一个对象并初始化它,返回指向此对象的shared_ptr。与智能指针一样,make_shared也定义在头文件memory 中。

//指向一个值为42的int的shared_ptr
shared_ptr<int> p3 = make_shared<int>(42);
//指向一个值为42的int的shared_ptr
shared_ptr<string> p4 = make_shared<string> (10,'9' ) ;
// p5指向一个值初始化的(参见3.3.1节,第88页) int,即,值为0
shared_ptr<int> p5 = make_shared<int> ();

shared_ptr会记录有多少个其他的shared_ptr指向相同的对象,通常认为有一个计数器,叫做引用计数,拷贝就会递增,当计数为0,就自动销毁管理的对象。拷贝一个shared_ ptr 会递增其引用计数;将一个shared_ ptr 赋予另一个shared_ ptr 会递增赋值号右侧shared ptr 的引用计数,而递减左侧shared_ ptr的引用计数。

程序使用动态内存出于下面三个原因:

1.程序不知道自己需要使用多少对象(容器类)

2.程序不知道所需对象的准确类型

3.程序需要在多个对象间共享数据(类中用智能指针指向共享内存)

指针与智能指针:

指针不能隐式转化为智能指针,必须直接初始化。

shared_ ptr<int> pl = new int (1024);//错误:必须使用直接初始化形式
shared_ptr<int> p2(new int (1024)); //正确:使用了直接初始化形式

使用普通指针访问智能指针的内存是很危险的,因为不知道什么时候对象会被销毁。

GET函数:

智能指针类型定义了一个名为get 的函数,它返回一个指针,指向智能指针管理的对象。此函数是为了这样一种情况而设计的:我们需要向不能使用智能指针的代码传递一个指针。使用get返回的指针的代码不能delete此指针。

get用来将指针的访问权限传递给代码,你只有在确定代码不会delete指针的情况下,才能使用 get。特别是,永远不要用 get初始化另一个智能指针或者为另一个智能指针赋值。

异常处理:

无论有一个函数有没有捕捉到异常,异常发生,离开函数,引用计数为0,智能指针都会释放内存。

智能指针使用规范:

unique_ptr:

一个unique ptr“拥有”它所指向的对象,某一时刻,只能由一个unique_ptr指向一个对象

与shared _ptr不同,没有类似 make_shared的标准库函数返回一个unique ptr。当我们定义一个unique_ptr时,需要将其绑定到一个new返回的指针上。类似shared ptr,初始化unique _ptr必须采用直接初始化形式:

unique _ptr<double> pl;// 可以指向一个double的unique_ptr
unique _ptr<int> p2(new int (42));// p2指向一个值为42的int

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

不能拷贝unique ptr的规则有一个例外:我们可以拷贝或赋值一个将要被销毁unique ptr。最常见的例子是从函数返回一个unique_ptr:

weak_ptr:

weak_ptr(见表12.5)是一种不控制所指向对象生存期的智能指针,它指向由一个shared_ptr管理的对象。将一个 weak _ptr 绑定到一个shared_ptr 不会改变shared _ptr的引用计数。一旦最后一个指向对象的shared_ptr被销毁,对象就会被释放。即使有 weak ptr指向对象,对象也还是会被释放,因此,weak _ptr的名字抓住了这种智能指针“弱”共享对象的特点。


当我们创建一个weak_ptr时,要用一个shared_ptr来初始化它:

auto p = make_shared<int> (42);

weak ptr<int> wp(p);// wp弱共享p;p的引用计数未改变

由于对象可能不存在,我们不能使用weak_ptr直接访问对象,而必须调用lock,存在会返回一个shared_ptr对象。

if (shared_ ptr<int> np = wp.lock()) { //如果np不为空则条件成立
//在if中,np与p共享对象
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值