参考:《C++ primer 第五版》

https://www.cnblogs.com/boydfd/p/5146432.html (需要多看几遍)

前言

程序中常用的存储形式如下。

静态内存:static对象,类static的数据成员,函数外的变量。

栈内存:函数内的非static对象。

自由空间或堆:动态分配的对象,程序控制生命周期。

动态内存与智能指针

从前,我们使用运算符new和delete来管理动态内存。但是使用很容易出错误,造成泄露。

新标准提供两个智能指针,shared_ptr和unique_ptr,来自动释放管理的动态对象。前者可以多个指针指向同一个对象,后者独占对象。另外还有weak_ptr,是一个伴随类,弱引用,指向shared_ptr管理的对象。

常见的用法(我们注意其中的get(),我觉得智能指针,并不是指针可以看作是指针的管理器):

shared_ptr

make_shared,这是最安全的分配使用方式,他是使用参数的构造函数来生成对像,也就是参数必须符合构造函数的参数表。我们通常使用auto来保存他返回的结果。

shared_ptr会记录有多少个shared_ptr指向同一个对象,当我们拷贝或者赋值一个shared_ptr时,计数器加一,被销毁则减一,为0则释放内存(析构函数)。

shared_ptr和new的结合使用

它的构造函数是explicit的,内置指针不能隐式的转换为智能指针,只能使用初始化的形式。

   shared_ptr<int> p1 = new int(11);   //错误,必须使用直接初始化形式shared_ptr<int> p2( new int(11) );   //正确,使用直接初始化shared_ptr<int> p3 = shared_ptr<int>( new int(12) ); //同上

不要混合使用普通指针和智能指针

   void process( shared_ptr<int> ptr ){} //离开,ptr被销毁//显式的,正确的shared_ptr<int> p(new int(42));process(p);int i =*p;//临时的shared_ptr,错误的int *x( new int(1024) );process(x); //错误,不能转化process( shared_ptr<int>(x) );  //x在这里被释放掉int j = *x;  //错误,这里是一个空悬指针

不要使用get来初始化另一个智能指针或为智能指针赋值

   shared_ptr<int> p( new int(42) );  //引用计数为1int *q = p.get();   //正确,我们不可以使用delete释放q{shared_ptr<int> (q); //和p指向了同一个地址, 这里的计数还是1} //程序块结束, q被销毁, 指向的内存被释放int foo = *p; //非法的指针,为空悬指针

如果使用的智能指针管理的不是new分配的内存(或者说delete无法释放的内存)那么我们定义一个删除器函数完成对其的释放工作。

shared_ptr<yourtype> p( &c, end_yourtype ) //end_yourtype为删除器,无论正常退出或异常都会释放
unique_ptr

某一时刻只能有一个unique_ptr指向一个给定的对象。下表列出它特有的操作,相同的在第一个表中。

我们不能拷贝或复制unique_ptr,但是可以使用release()和reset()转交给另一个unique。

重载unique_ptr中删除器时,必须在<>中提供删除器的类型。

在C++14中,已经支持make_unique<>()方法。可以参考make_shared,但是make_都不支持添加删除器,或者初始化列表。

 auto b = make_shared<vector<int>>({1,2,3}); // 错误

weak_ptr,是一种不控制所指向对象生存周期的智能指针,指向一个shared_ptr管理的对象,他不会增加引用计数。常用操作:

我们使用lock()来判断是否为空,他是为了解决循环引用的问题。

#include<memory>
#include<iostream>using namespace std;
class B;
class A
{
public:// 为了省去一些步骤这里 数据成员也声明为public
//    weak_ptr<B> pb;shared_ptr<B> pb;void doSomthing(){
//        if(pb.lock())
//        {
//
//        }}~A(){cout << "kill A\n";}
};class B
{
public:
//        weak_ptr<A> pa;shared_ptr<A> pa;~B(){cout <<"kill B\n";}
};int main()
{shared_ptr<A> sa(new A());shared_ptr<B> sb(new B());if(sa && sb){sa->pb=sb;sb->pa=sa;}cout<<"sa use count:"<<sa.use_count()<<endl;cout<<"sa use count:"<<sb.use_count()<<endl;return 0;
}

如果使用shared_ptr,结果为2,并且不会调用析构函数(不输出kill).

shared_ptr的详解相关推荐

  1. C++智能指针: shared_ptr 实现详解

    文章目录 shared_ptr描述 声明 作用 原理实现 函数使用 关于shared_ptr循环引用问题 shared_ptr描述 声明 shared_ptr属于C++11特性中新加的一种智能指针,它 ...

  2. C++智能指针:weak_ptr实现详解

    文章目录 weak_ptr描述 声明 作用 原理实现 函数成员使用 总结 weak_ptr描述 声明 头文件:<memory> 模版类:template <class T> c ...

  3. C++ 智能指针详解

    智能指针内容很多,重点是基本用法. #include <boost/shared_ptr.hpp> class CBase: public boost::enable_shared_fro ...

  4. c++ 智能指针_详解 C++ 11 中的智能指针

    C/C++ 语言最为人所诟病的特性之一就是存在内存泄露问题,因此后来的大多数语言都提供了内置内存分配与释放功能,有的甚至干脆对语言的使用者屏蔽了内存指针这一概念.这里不置贬褒,手动分配内存与手动释放内 ...

  5. 详解C++11智能指针

    详解C++11智能指针 前言 C++里面的四个智能指针: auto_ptr, unique_ptr,shared_ptr, weak_ptr 其中后三个是C++11支持,并且第一个已经被C++11弃用 ...

  6. C++11 并发指南三(Lock 详解)

    在 <C++11 并发指南三(std::mutex 详解)>一文中我们主要介绍了 C++11 标准中的互斥量(Mutex),并简单介绍了一下两种锁类型.本节将详细介绍一下 C++11 标准 ...

  7. C++ - 类模板(class template) 详解 及 代码

    类模板(class template) 详解 及 代码 本文地址: http://blog.csdn.net/caroline_wendy/article/details/16906827 类模板(c ...

  8. C++11 并发指南三(Lock 详解)(转载)

    multithreading 多线程 C++11 C++11多线程基本使用 C++11 并发指南三(Lock 详解) 在 <C++11 并发指南三(std::mutex 详解)>一文中我们 ...

  9. folly::ConcurrentSkipList 详解

    SkipList 原理及构造过程 SkipList 是受多层链表的启发而设计出来的.实际上,最理想的情况是上面每一层链表的节点个数,是下面一层的节点个数的一半,这样查找过程就非常类似于一个二分查找,使 ...

最新文章

  1. oracle集群 节点切换不,Oracle 11gR2 RAC集群单节点关闭开启
  2. Windows下PHP多线程扩展pthreads的安装
  3. 吃鸡电脑配置清单_2020电脑配置游戏装机清单(覆盖主流游戏)
  4. 庆祝我的第一本书出版
  5. Atiitt 软件设计之道 attilax著 1. 总概念 隶属于软件工程。。 2 2. 需求分析 3 3. 设计分类 3 3.1. 按照力度 总体设计架构设计 概要设计 详细设计 3 3.2.
  6. 粒子群算法优化BP和Elman神经网络-matlab源码
  7. 品管(QC)七大手法
  8. WebPlotDigitizer使用教程
  9. 一文读懂“语言模型”
  10. 计算快递费系统(java版)
  11. 全职高手24职业及技能(Full time master)
  12. TMS320F28379D创建工程
  13. python3.8如何正确安装使用ExcelLibrary
  14. 文字转化为二维码(数据加密)
  15. Java虚拟机--判断可触及性(七)
  16. C++ 的 Copy Elision
  17. ISO SAE 21434-2021 要求、建议、允许(RQ、RC、PM)整理
  18. opencv h264压缩视频
  19. 玩转OneNET物联网平台之简介
  20. “做中学学中做”教学模式在计算机基础教学中的应用探索

热门文章

  1. MediaPlayer音视频播放
  2. Java学习笔记2.5.3 循环结构 - 循环嵌套
  3. .NET 6新东西--PeriodicTimer
  4. LinkCloud谈云主机与主机托管主机租用的区别
  5. join left loke mysql_MySQL 使用经验
  6. React之函数式组件和高阶组件(装饰器、带参装饰器)
  7. R语言画图——添加数学表达式和R2(Ⅱ)
  8. 邮政快递单号可以批量查询吗
  9. C#毕业设计——基于C#+asp.net+sqlserver药店进销存管理系统设计与实现(毕业论文+程序源码)——进销存管理系统
  10. android登陆界面设计方案,011android初级篇之android登录界面的设计