参考:https://blog.csdn.net/u011068702/article/details/83692838

1  智能指针std::shared_ptr相关知识和如何使用
我们这里先说下智能指针std::shared_ptr,因为我看到我我们项目c++代码里面用得很多,我不是不会,所以记录学习下

先让ubuntu终端支持c++11,如果自己的电脑还没配置号,可以先看下我的这篇博客linux之让终端支持C++11/14编译cpp文件

1)  所在的头文件

#include <memory>

2)  介绍:

shared_ptr是一种智能指针(smart pointer),作用有如同指针,但会记录有多少个shared_ptrs共同指向一个对象。这便是所谓的引用计数(reference counting),比如我们把只能指针赋值给另外一个对象,那么对象多了一个智能指针指向它,所以这个时候引用计数会增加一个,我们可以用shared_ptr.use_count()函数查看这个智能指针的引用计数,一旦最后一个这样的指针被销毁,也就是一旦某个对象的引用计数变为0,这个对象会被自动删除,当我们程序结束进行return的时候,智能指针的引用计数会减1,不知道我理解有没有问题.有的话请老铁们指出.

3)  share_ptr的三种初始化方法
     1.通过一个指向堆上申请的空间的指针初始化(切记不要用栈上的指针,否则,当智能指针全部释放控制权(栈中的对象离开作用域本身就会析构一次),将会析构对象,导致出错)

比如如下

int a = new int(100);
 
     std::shared_ptr ptr(a); //我们不能写成std::shared_ptr ptr = a;这样写错误,不行你编译运行看下,编译不过

2.  通过make_shared函数得到

std::shared_ptr<int> ptr1 = std::make_shared<int>(15);
     3 拷贝初始化

std::shared_ptr<int> ptr2(ptr1);
    //std::shared_ptr<int> ptr2 = ptr1;这样赋值是错误的,只要是智能指针,这样直接用=赋值是有问题的必须std::shared_ptr<int> ptr2(ptr1);

4)  reset函数

当只能指针调用了reset函数的时候,就不会再指向这个对象了,所以如果还有其它智能指针指向这个对象,那么另外一个智能指针的use_count()函数结果会减1

5)  智能指针的enable_shared_from_this和shared_from_this

为什么要用到enable_shared_from_this和shared_from_this,比如我们写一个普通的类,有析构函数,一个智能指针指向类对象的时候,我们析构函数会析购一次,然后智能指针会析构一次,析构两次就有问题,如下写法

Student{
    Student(){}
    ~Student()
    {
        std::cout << "~Student被调用" << std::endl;    
    }
    std::shared_ptr<Student> getStudent()
    {
        return std::shared_ptr<Student>(this);    
    } 
};
所以我们一般用这个类继续enable_shared_from_this<Student>,然后getStudent函数的时候返回shared_from_this()这个就行

6 ) 如何判断智能指针是否为null,我么可以使用get()函数,比如

std::shared_ptr<int> ptr(new int(100));
if (ptr.get()) {
    std::cout << "ptr is not null" << std::endl;
} else {
    std::cout << "ptr is null" << std::enel;
}
 
2  测试Demo
#include <iostream>
#include <memory>
using namespace std;
class Student : public enable_shared_from_this<Student>
{
public:
        Student() {}
    ~Student()
    {
        std::cout << "~Student被调用" << std::endl;    
    }
    std::shared_ptr<Student> getStudent()
    {
        return shared_from_this();    
    } 
    std::string name;
    void setName(std::string name);
    std::string getName();
};
void Student::setName(std::string name)
{
    this->name = name;    
}
std::string Student::getName()
{
    return name;    
}
int main()
{
    int *p = new int(10);    
    //std::shared_ptr<int> ptr = p;这样赋值是错误的额,只要是智能指针,这样直接用=赋值是有问题的必须std::shared_ptr<int> ptr(p);
    std::shared_ptr<int> ptr(p);
    std::shared_ptr<int> ptr1 = std::make_shared<int>(15);
    std::shared_ptr<int> ptr2(ptr1);
    //std::shared_ptr<int> ptr2 = ptr1;这样赋值是错误的,只要是智能指针,这样直接用=赋值是有问题的必须std::shared_ptr<int> ptr2(ptr1);
    std::cout << "ptr.use_count() is:" << ptr.use_count() << "  *ptr is:" << *ptr << std::endl;
    std::cout << "ptr1.use_count() is:" << ptr1.use_count() << "  *ptr1 is:" << *ptr1 << std::endl;
    std::cout << "ptr2.use_count() is:" << ptr2.use_count() << "  *ptr2 is:" << *ptr2 << std::endl;
    
    ptr2.reset();
    //这是时候ptr2已经销毁,指向的对象引用计数会减1,这个指针的不再指向任何对象,所以我们不能使用*ptr2了,下面一行代码使用肯定会报错,我先注释掉
    //std::cout << "ptr2.use_count() is:" << ptr2.use_count() << "*ptr2 is:" << *ptr2 << std::endl;
        std::cout << "ptr1.use_count() is:" << ptr1.use_count() << "   *ptr1 is:" << *ptr1 << std::endl;
    Student *stu = new Student();
    std::shared_ptr<Student> ptr_stu(stu);
    std::string name = "chenyu";
    ptr_stu->setName(name);
    std::string result = ptr_stu->getName();
        std::cout << "ptr_stu.use_count() is:" << ptr_stu.use_count() << std::endl;
    std::cout << "my name is:" << result << std::endl;
        return 0;
}

3  运行结果以及分析
ptr.use_count() is:1  *ptr is:10
ptr1.use_count() is:2  *ptr1 is:15
ptr2.use_count() is:2  *ptr2 is:15
ptr1.use_count() is:1   *ptr1 is:15
ptr_stu.use_count() is:1
my name is:chenyu
~Student被调用
很明显调用了reset之后,引用技术减1了,然后程序在return的时候,ptr和ptr1和ptr_stu的引用计数会变为0,所以指向的对象就会自动销毁,所以不会导致内存泄漏
————————————————
版权声明:本文为CSDN博主「chen.yu」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/u011068702/article/details/83692838

以下内容来自:https://www.zhihu.com/tardis/sogou/qus/20368881

从较浅的层面看,智能指针是利用了一种叫做RAII(资源获取即初始化)的技术对普通的指针进行封装,
这使得智能指针实质是一个对象,行为表现的却像一个指针
作用当然很明显,防止忘记调用delete,当然还有另一个作用, @胡昊 也指出来了,就是异常安全。在一段进行了try/catch的代码段里面,即使你写入了delete,也有可能因为发生异常,程序进入catch块,从而忘记释放内存,这些都可以通过智能指针解决。

但是智能指针还有一重更加深刻的含义,就是把 @陈硕所说的value语义转化为reference语义
C++和Java有一处最大的区别在于语义不同,在Java里面下列代码:

Animal a = new Animal();
Animal b = a;
你当然知道,这里其实只生成了一个对象,a和b仅仅是把持对象的引用而已。但在C++中不是这样,
Animal a;
Animal b;
这里确实就是生成了两个对象。
在编写OOP程序时,value语义带来太多的困扰,例如TCP连接中我封装一个accept函数接收请求,那么应该是这样的:
Socket accept();
这就带来一个问题,采用对象做返回值,这里面有一个对象的复制的过程,但是Socket因为某些原因,我让他继承了boost::noncopyable,总之就是Socket失去了复制和赋值的能力,那么该怎么办?
我们首先想到指针,在accept内部new生成一个对象,然后返回指针。但是问题更多,这个对象何时析构? 过早析构,程序发生错误,不进行析构,又造成了内存泄露。
这里的解决方案就是智能指针,而且是引用计数型的智能指针。
typedef boost::shared<Socket> SocketPtr;
SocketPtr accept();
这样外部就可以用智能指针去接收,那么何时析构?当然是引用计数为0,也就是我不再需要这个Socket的时候析构。
这样,我们利用了SockerPtr,实现了跟Java类似的Reference语义。

还有一个例子,Java中往容器中放对象,实际放入的是引用,不是真正的对象,而C++在vector中push_back采用的是值拷贝,如果想实现Java中的引用语义,就应该使用智能指针,可以参考《C++标准库程序》(侯捷/孟岩 译)的第五章讲容器的部分,有一节叫做“用Value语义实现Reference语义”

C++ 智能指针std::shared_ptr简单使用和理解相关推荐

  1. C++之智能指针std::shared_ptr简单使用和理解

    前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家.点击跳转到教程 1  智能指针std::shared_ptr相关知识和如何使用 我们这里先说下智能指针std::sha ...

  2. c语言 ptr 用法,C++之智能指针std::shared_ptr简单使用和理解

    1  智能指针std::shared_ptr相关知识和如何使用 我们这里先说下智能指针std::shared_ptr,因为我看到我我们项目c++代码里面用得很多,我不是不会,所以记录学习下 先让ubu ...

  3. C++笔记:智能指针 std::shared_ptr

    1. 语法 std::shared_ptr<类型> 变量名称{}: std::shared_ptr<int> ptrA{};std::shared_ptr<int> ...

  4. C++11 智能指针之shared_ptr

    0.Overview 在实际的 C++ 开发中,我们经常会遇到诸如程序运行中突然崩溃.程序运行所用内存越来越多最终不得不重启等问题,这些问题往往都是内存资源管理不当造成的.比如: 有些内存资源已经被释 ...

  5. C++ 实现智能指针:shared_ptr 和 unique_ptr

    简 述: C++11 智能指针的深入分析,和动手实现简版的智能指针 std::shared_ptr .std::unique_ptr 文章目录 背景 std::shared_ptr 原理 代码 ref ...

  6. 【C++11新特性】 C++11智能指针之shared_ptr

    http://blog.csdn.net/Xiejingfa/article/details/50750037 原创作品,转载请标明:http://blog.csdn.net/Xiejingfa/ar ...

  7. C++智能指针:更简单、更高效的内存管理方法

    C++智能指针:从新手到高手的心理密码C++ Smart Pointers: Psychological Passcodes from Beginner to Expert 智能指针简介 (Intro ...

  8. 【C++11智能指针】shared_ptr的初始化、拷贝构造和拷贝赋值、移动构造和移动赋值

    文章目录 1.智能指针概述 2.shared_ptr的初始化 2.1 shared_ptr和new结合使用(直接初始化) 2.2 make_shared函数 3.shared_ptr的拷贝构造和拷贝赋 ...

  9. 智能指针之shared_ptr易错点05

    一 shared_ptr易错点 1 慎用裸指针给shared_ptr赋值 例1 class A {public:A() {};A(int i) {m_i=i;cout<<"A&q ...

最新文章

  1. 云栖科技评论 | 传统产业的数字化转型 破除“肌肉记忆” 拥抱变化与未知
  2. python中文软件-Python编程软件下载
  3. HTML 5 令人期待的 5 项功能
  4. 一款零注解API接口文档生成工具
  5. sql常用语法命令及函数_SQL右连接命令:语法示例
  6. lua协程的使用列子分析
  7. 制造业实施大数据战略面临哪些挑战
  8. centos7中Python切换到Python3.x版本(解决常出现的错误)
  9. react 路径跳转组件不跳转_Taro 小程序开发大型实战(二):多页面跳转和 Taro UI 组件库...
  10. CloudCompare 软件手册
  11. oracle 获得节假日,Oracle 计算两个日期间时间排除非工作日及非工作时间
  12. 在线图片处理api接口
  13. 按键精灵版QQ自动加好友脚本分享
  14. 免费天气API,天气JSON API,天气插件
  15. 马云:我不为996辩护,我向奋斗者致敬
  16. 草图实时生成动漫角色!太秀了
  17. Python爬虫练习:爬取猫眼电影实时票房
  18. Excel 函数大全之查找和引用函数 01 ADDRESS、AREAS、CHOOSE 、CHOOSECOLS、CHOOSEROWS、COLUMN 、COLUMNS教程含使用方法
  19. python机器人编程——差速AGV机器、基于视觉和预测控制的循迹、自动行驶(上篇)
  20. GB2312的中文编码表

热门文章

  1. 结合typedef更为直观的应用函数指针
  2. TCP/IP详解--第九章
  3. 添加linux系统调用的两种方式
  4. 如何判断 Linux 是否运行在虚拟机上
  5. php sql server配置文件路径,云服务器初始化 第六章:更改MySQL数据文件存放路径...
  6. rs485数据线接反_再拆一个RS232-RS485通信接口转换器
  7. blog微服务架构代码_聊聊微服务架构
  8. java中布局管理器flowlayout,在Java中下列()方法可以把JFrame的布局管理器设为FlowLayout类型。...
  9. mega_[MEGA DEAL] 2018 Essential JavaScript编码捆绑包(96%折扣)
  10. unix修改ip和计算机名,UNIX shell获取IP和修改IP