智能指针(smart pointer)


智能指针的行为类似常规指针,重要的区别在于智能指针负责自动释放所指向的对象,头文件memory
shared_ptr : 允许多个智能指针指向同一个对象
unique_ptr : 一个指针“独占”所指向的对象
weak_ptr : 弱引用,指向shared_ptr所管理的对象
shared_ptr:

1.创建一个shared_ptr,必须提供指针指向的类型,命名格式:shared_ptr<类型> 指针名;
例如:shared_ptr<string> sptr 或 shared_ptr<vector<int>> vctptr,上述形式的初始化,返回的智能指针中保存一个空指针
 
2.与普通指针相似,解引用(*)智能指针返回它指向的对象
 
3.shared_ptr支持的操作,参看c++ primer 5 Edition P401
 
4.make_shared函数:作为智能指针的初始化方式之一,安全的分配和使用动态内存。功能:在动态内存中,分配一个对象并初始化,返回此对象的shared_ptr,
格式:shared_ptr<类型> 指针名 = make_shared<类型>();例如:
shared_ptr<int> iptr = make_ptr<int>(); // 使用int的默认构造函数,初始化shared_ptr对象的内容
shared_ptr<int> iptr = make_ptr<int>(36); // 使用int的重载构造函数,初始化shared_ptr对象的内容为36

5.shared_ptr的拷贝和赋值

当拷贝和赋值操作时,每个shared_ptr都会记录有多少个其他的shared_ptr指向相同的对象,即:每个shared_ptr都有一个关联的计数器,引用计数;无论何时拷贝(赋值)一个shared_ptr,计数器都会递增。
 
递增的情况有三种(这里类似复制构造函数,存在的情形):
a.用一个shared_ptr初始化另外一个shared_ptr
b.作为函数参数传参(拷贝实参对象)
c.作为函数返回值(返回出来还是要赋值)
指向同一对象的所有shared_ptr指针的计数都相同,同时更新(+1或-1),一旦计数器变为0,则会自动释放shared_ptr所管理的对象
智能指针初始化方式:
shared_ptr<int> iptr = make_shared<int>(5);
cout << iptr.use_count() << endl;
shared_ptr<int> data = make_shared<int>(1); // 初始化方式1:make_shared
// shared_ptr<int> data(iptr); 初始化方式2:直接初始化
iptr = data; // 初始化方式3:赋值:智能指针之间相互赋值
cout << *iptr << endl;
cout << data.use_count() << endl;
智能指针只能用只能指针来初始化,或者相互赋值;不能用内置类型指针来赋值,可以用内置类型指针直接初始化

6.shared_ptr自动销毁管理对象,也会自动释放相关联的动态内存
指向一个对象的最后一个shared_ptr销毁时,shared_ptr类会自动销毁此对象,该类中有析构函数,shared_ptr的析构函数会自动递减它所指向的对象的引用计数,当变为0时,shared_ptr的析构函数就会销毁对象,并释放占用的内存。
对于一块内存,shared_ptr类保证只要有任何shared_ptr对象引用它,就不会被释放掉
例子1:
// func返回一个shared_ptr,指向一个动态分配的对象
shared_ptr<foo> func(T arg) {return make_shared<foo>(arg);
}
foo类,使用T类型参数arg,通过构造函数初始化一块内存,nake_shared函数将该内存地址返回给智能指针shared_ptr,并作为函数func的返回值,返回一个shared_ptr,可以确保在函数体内申请的动态内存会在恰当的时刻被释放

例子2:
void func2(T arg) {shared_ptr<foo> p = make_shared<foo>(arg);// 使用p, 当p离开作用域,它指向的内存会被自动释放
}

例子3:
shared_ptr<foo> func3(T arg) {shared_ptr<foo> p = make_shared<foo>(arg);return p;  // 使用p,当返回p时,引用计数进行了递增操作,当p离开作用域,它指向的内存会被自动释放
}
return语句向此函数的调用者返回一个P的拷贝。拷贝一个shared_ptr会增加所管理的对象的引用计数值;当p销毁时,该内存还有其他使用者,内存就不会被释放

如果忘记了销毁程序不再需要的shared_ptr,程序仍然会正常运行,但是会浪费内存。shared_ptr在无用之后仍然保留的一种可能情况:shared_ptr放在容器中,然后重排了容器,从而不再需要某些元素,在这种情况下,应该erase删除不需要的shared_ptr指针。

7.shared_ptr一些初始化操作:直接内存管理(参考内存管理---直接内存管理)
前面5提到过shared_ptr的初始化,总结一下:
1.不进行初始化,会自动初始化为一个空指针nullptr
shared<类型> 指针名;例如:shared_ptr<int> pi;
2.使用内置类型指针直接初始化
shared_ptr<类型> 指针名(内置类型指针p); 这里的p --> 类型* p = new 类型()
shared_ptr<类型> 指针名(new<类型>())// shared_ptr与new结合使用
3.shared_ptr<类型> 指针名(智能指针ptr); // 使用智能指针直接初始化
4.shared_ptr<类型> 指针名 = 智能指针ptr; //智能指针赋值初始化
5.shared_ptr<类型> 指针名 = make_shared<类型>(); // make_shared函数初始化

不能将一个内置指针隐式的转换成一个智能指针,必须使用直接初始化的形式
一个用来初始化智能指针的普通指针必须指向动态内存,因为智能指针默认使用delete释放它所关联的对象

8.定义改变shared_ptr的其他方法  参看c++ primer 5 Edition P412-413
9.不要混合使用普通指针和智能指针
当一个shared_ptr绑定到一个普通指针时,就将内存的管理责任交给了shared_ptr
10.不要使用智能指针get()方法初始化另一个智能指针或者智能指针赋值
get()方法可以获取该智能指针的对应的内置指针,该内置指针指向智能指针管理的对象
使用get()返回的指针代码不能delete此指针,因为该返回的内置指针指向智能指针管理的对象,该对象的释放由智能指针来管理
11.智能指针和异常:智能指针可以保证当程序发生异常时,仍旧能正确的释放资源

转载于:https://www.cnblogs.com/zhang716921/p/10626709.html

内存管理之智能指针shared_ptr相关推荐

  1. 动态内存管理和智能指针 2.0 -- shared_ptr

    shared_ptr出现原因 通过第一章的学习,我们知道不管是auto_ptr合适scoped_ptr都是存在缺陷的,于是我们必须想出一个方法既能很好的管理我们的内存,而且在使用的时候,可以多个指针指 ...

  2. C++ 使用智能指针shared_ptr/unique_ptr管理数组

    目录 零.要管理的类 一.使用shared_ptr管理数组 二.使用unique_ptr管理数组 1.第一种方式 2.第二种方式 关于shared_ptr/unique_ptr的基础,我不在本篇博客中 ...

  3. Boost智能指针——shared_ptr

    boost::scoped_ptr虽然简单易用,但它不能共享所有权的特性却大大限制了其使用范围,而boost::shared_ptr可以解决这一局限.顾名思义,boost::shared_ptr是可以 ...

  4. 标准库中的智能指针shared_ptr

    智能指针的出现是为了能够更加方便的解决动态内存的管理问题.注:曾经记得有本书上说可以通过vector来实现动态分配的内存的自动管理,但是经过试验,在gcc4.8.5下是不行的.这个是容易理解的,vec ...

  5. get方法报空指针_智能指针shared_ptr踩坑笔记

    平时写代码一直避免使用指针,但在某些场景下指针的使用还是有必要的.最近在项目中简单使用了一下智能指针(shared_ptr),结果踩了不少坑,差点就爬不出来了.痛定思痛抱着<Cpp Primer ...

  6. 智能指针shared_ptr

    如果有可能就使用unique_ptr,然后很多时候对象是需要共享的,因此shared_ptr也就会用得很多.shared_ptr允许多个指向同一个对象,当指向对象的最后一个shared_ptr销毁时, ...

  7. 【Boost】boost库中智能指针——shared_ptr

    boost::scoped_ptr虽然简单易用,但它不能共享所有权的特性却大大限制了其使用范围,而boost::shared_ptr可以解决这一局限.顾名思义,boost::shared_ptr是可以 ...

  8. C++智能指针shared_ptr、unique_ptr以及weak_ptr

    目录 shared_ptr类 shared_ptr和unique_ptr都支持的操作 shared_ptr独有的操作 make_shared函数 shared_ptr自动销毁所管理的对象 由普通指针管 ...

  9. 智能指针(shared_ptr、unique_ptr、weak_ptr)的使用

    智能指针的使用 一.shared_ptr 1.创建一个shared_ptr 2.shared_ptr的常用成员函数 reset成员函数的使用 3.==注意事项== 二.unique_ptr 1.uni ...

  10. 智能指针shared_ptr的原理、用法和注意事项

    智能指针shared_ptr的原理.用法和注意事项 1 前言 2 shared_ptr原理 3 shared_ptr的基本用法 3.1 初始化 3.2 获取原始指针 4 智能指针和动态数组 4.1 c ...

最新文章

  1. Vivadoz中Block Memory Generator v8.3的使用方法(二)
  2. 剑指 Offer 29. 顺时针打印矩阵
  3. VTK:vtkCompositePolyDataMapper2用法实战
  4. vs里根据json快速创建对应类的方法
  5. pandas 分层取5个数据_Pandas数据可视化的9个要点「附案例」
  6. 面向对象之反射和其他内置方法
  7. 魅族前副总裁李楠谈“苹果对5G判断”,理解万岁!
  8. Python之对list进行切片
  9. 嵌套循环连接(Nested Loops), 合并联接(Merge), 哈希联接(Hash)的适用情况
  10. Android之WindowManager+OpenGL+EGL绘制(十七)
  11. 高等数学复习笔记(二)- 一元函数微分学的概念、计算以及几何应用
  12. 数学建模案例【人口模型 】(马尔萨斯人口模型,Logistic模型)
  13. 微信小程序等第三方应用接入易班的api
  14. 美食杰(个人主页) 上
  15. python调研报告总结体会_调查报告的心得体会
  16. 备份数据库 并发送到邮箱
  17. 什么是 FOUC(无样式内容闪烁)?你如何来避免 FOUC?
  18. PyQt5中ImportError: DLL load failed while importing QtCore: 鎵句笉鍒版寚瀹氱殑妯″潡銆�问题解决
  19. 攻击JavaWeb应用[3]-SQL注入[1]
  20. pythonocc view coordinate_pythonOCC例子搬运:4.经典瓶子造型

热门文章

  1. uitableView group模式下的间距问题
  2. IDEA14创建Maven管理的Java Web项目
  3. uip UDP 服务器广播模式(客户端可以任意端口,并且主动向客户端发送数据) (转)...
  4. Oracle 数字与空值的排序问题
  5. window上安装fasttext
  6. ICLR 审稿人:这篇论文在标签平滑和知识蒸馏的关系上取得了重大突破!
  7. Bert做不好无监督文本匹配的原因找到了!!
  8. 研究所月入两万?见过越上班工资越少的骚操作吗...
  9. 每日算法系列【LeetCode 124】二叉树中的最大路径和
  10. 神奇的G1——Java全新垃圾回收机制