C++知识点5:C++11 shared_ptr(智能指针)详解

1 C++11 shared_ptr(智能指针)详解

内容参考知乎,由于写的非常详细,直接拿过来用了

要确保用 new 动态分配的内存空间在程序的各条执行路径都能被释放是一件麻烦的事情。C++ 11 模板库的 头文件中定义的智能指针,即 shared _ptr 模板,就是用来部分解决这个问题的。

shared_ptr采用引用计数的方式管理所指向的对象。当有一个新的shared_ptr指向同一个对象时(复制shared_ptr等),引用计数加1。当shared_ptr离开作用域时,引用计数减1。当引用计数为0时,释放所管理的内存。

只要将 new 运算符返回的指针 p 交给一个 shared_ptr 对象“托管”,就不必担心在哪里写delete p语句——实际上根本不需要编写这条语句,*托管 p 的 shared_ptr 对象在消亡时会自动执行delete p。而且,该 shared_ptr 对象能像指针 p —样使用,即假设托管 p 的 shared_ptr 对象叫作 ptr,那么 ptr 就是 p 指向的对象。

通过 shared_ptr 的构造函数,可以让 shared_ptr 对象托管一个 new 运算符返回的指针,写法如下:

shared_ptr<T> ptr(new T);  // T 可以是 int、char、类等各种类型

此后,ptr 就可以像 T* 类型的指针一样使用,即 *ptr 就是用 new 动态分配的那个对象。

多个 shared_ptr 对象可以共同托管一个指针 p,当所有曾经托管 p 的 shared_ptr 对象都解除了对其的托管时,就会执行delete p

代码使用如下

#include"ros/ros.h"
#include<iostream>
#include<memory>
using namespace std;
class A
{
private:
    /* data */
public:
    int i;
    A(int n):i(n){};
    ~A(){cout<<i<<" "<<"destructed"<<endl;};
};

int main(int argc, char *argv[])
{
    setlocale(LC_ALL,"");
    ros::init(argc,argv,"ergouzi_colass");
    ros::NodeHandle nh;
    //shared_ptr可以使用一个new表达式返回的指针进行初始化。
    shared_ptr<A> sp1(new A(2));  //A(2)交由sp1管理
    //但是,不能将一个new表达式返回的指针赋值给shared_ptr。
    //shared_ptr<int> p5 = new int(1024); // wrong, no implicit constructor
    shared_ptr<A> sp2(sp1);   //A(2)同时交由sp2托管
    shared_ptr<A> sp3;
    sp3=sp2;    ///A(2)同时交由sp3托管
    cout<<sp1->i<<","<<sp2->i<<","<<sp3->i<<endl;
    A *p=sp3.get();  //get返回托管的指针,p指向A(2)
    cout<<p->i<<endl;
    sp1.reset(new A(3));  // reset导致托管新的指针, 此时sp1托管A(3),同时解除对原托管指针的托管
     sp2.reset(new A(4));  //sp2托管A(4)
     cout<<sp1->i<<","<<sp2->i<<","<<sp3->i<<endl;
     sp3.reset(new A(5)); // // sp3托管A(5),A(2)无人托管,被delete

    return 0;
    //main 函数结束时,sp1、sp2、sp3 对象消亡,各自将其托管的指针的托管计数减为 0,并且释放其托管的指针
}

程序运行结果为:
请添加图片描述

注意,不能用下面的方式使得两个 shared_ptr 对象托管同一个指针:

A* p = new A(10);
shared_ptr <A> sp1(p), sp2(p);

sp1 和 sp2 并不会共享同一个对 p 的托管计数,而是各自将对 p 的托管计数都记为 1(sp2 无法知道 p 已经被 sp1 托管过)。这样,当 sp1 消亡时要析构 p,sp2 消亡时要再次析构 p,这会导致程序崩溃。
此外,注意:
hared_ptr.reset

shared_ptr可以通过reset方法重置指向另一个对象,此时原对象的引用计数减一。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

星辰和大海都需要门票

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值