智能指针-shared_ptr类

shared_ptr是模板,允许多个指针指向同一个对象,定义时需提供指针可以指向的类型,如:

shared_ptr<string> p1;//shared_ptr,可以指向string
shared_ptr<list<int>> p2;//shared_ptr,指向int的list
shared_ptr和unique_ptr常见的操作如下:

这里写图片描述

shared_ptr独有的操作如下:

这里写图片描述
最安全的分配和使用动态内存的方法是调用一个名为make_shared的标准库函数,该函数存在于头文件memory中,此函数在动态内存中分配一个对象并初始化它,返回指向该对象的shared_ptr,如:

//指向一个值为42的int的shared_ptr
shared_ptr<int> p3=make_shared<int>(42);
//auto p3=make_shared<int>(42);

每个shared_ptr都有一个关联的计数器,记录有多少个其他shared_ptr指向相同的对象,称为引用计数。当我们拷贝一个shared_ptr,计数器会递增。当我们给shared_ptr赋予一个新值或是shared_ptr被销毁时,计数器会递减。一旦一个shared_ptr的计数器变成0,它会自动释放自己所管理的对象。

//r指向的int只有一个引用者
auto r=make_shared<int>(42);
r=q;//给r赋值,令它指向q所指向的地址
    //递增q所指向的对象的计数器,递减r所指向对象的计数器,若r的计数器为0,则自动释放
当指向一个对象的最后一个shared_ptr被销毁时,shared_ptr类会通过折构函数自动销毁此对象。shared_ptr的折构函数会递减它所指向的对象的引用计数,如果引用计数变为0,则折构函数会销毁对象,并释放它占用的内存。

程序适用动态内存一般基于以下三种原因:

1)程序不知道自己需要适用多少对象

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

3)程序需要在多个对象间共享数据

如果我们不初始化一个智能指针,它就会被初始化为一个空指针,我们也可以用new返回的指针来初始化智能指针。但需要注意的是接受指针参数的智能指针的构造函数是explicit的(阻止隐式转换),故利用new必须使用直接初始化。

这里写图片描述

这里写图片描述

但是我们可以将shared_ptr显式绑定到一个想要返回的指针上:

shared_ptr<int> clone(int p)
{
    return shared_ptr<int>(new int(p));
}

我们可以将智能指针绑定到一个指向其他类型的资源指针上,但必须提供自己的操作来代替delete.

这里写图片描述
这里写图片描述

混合使用普通指针和智能指针可能造成的错误。当将一个shared_ptr绑定到一个普通指针时,我们就将内存管理责任交给了这个shared_ptr.

这里写图片描述

智能指针类型定义了一个名为get的函数,它返回一个内置指针,指向智能指针管理的对象。使用get返回的指针的代码不能delete此指针。

这里写图片描述

智能指针需要坚持的规范:

(1)不使用相同的内置指针值初始化(或reset)多个智能指针。
(2)不delete get() 返回的指针
(3)不使用 get()初始化或reset另一个智能指针
(4)如果你使用get()返回的指针,记住当最后一个对应的智能指针被销毁后,你的指针就变成无效了
(5)如果你使用智能指针管理的资源不是new分配的内存,记住传递给它一个删除器。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值