zoukankan      html  css  js  c++  java
  • 关于智能指针类型shared_ptr的计数问题

    一、关键

    每个shared_ptr所指向的对象都有一个引用计数,它记录了有多少个shared_ptr指向自己

    shared_ptr的析构函数:递减它所指向的对象的引用计数,如果引用计数变为0,就会销毁对象并释放相应的内存

    引用计数的变化:决定权在shared_ptr,而与对象本身无关

    二、引用计数初步

    	shared_ptr<int> sp;						//空智能指针 
    	shared_ptr<int> sp2 = make_shared<int>(3);
    	shared_ptr<int> sp3(sp2);
    	cout << sp.use_count() << endl;			//输出0
    	cout << sp2.use_count() << endl;		//输出2
    

    注:sp.use_count()函数返回sp所指对象的引用计数

    三、引用计数增加的情况

    拷贝一个shared_ptr,其所指对象的引用计数会递增,如:

    • 用一个shared_ptr初始化另一个shared_ptr
    • 用一个shared_ptr给另一个shared_ptr赋值
    • 将shared_ptr作为参数传递给一个函数
    • shared_ptr作为函数的返回值

    四、引用计数减少的情况

    • 给shared_ptr赋予一个新值
    • shared_ptr被销毁(如离开作用域

    五、迷途返航

    1. 局部的shared_ptr离开其作用域,它所指对象的引用计数会递减(-1)

    假设:没有全局的shared_ptr,那么正确的结果应该是该shared_ptr所指的对象被销毁

    我之前错误的想法:多个局部shared_ptr共同指向同一个对象,那么该对象的引用计数就>1,该函数结束时对象的引用计数减1(但仍>0),那么该对象不应该被销毁。

    纠正想法:既然是多个局部shared_ptr指向该对象,那么函数结束时对象的引用计数就不应该只减1啊!!

    shared_ptr<int> init()
    {
    	shared_ptr<int> sp2 = make_shared<int>(3);
    	shared_ptr<int> sp3(sp2);
    	cout << sp2.use_count() << endl;		//输出2 
    	return sp2;								//返回sp2,故引用计数递增,变为3 
    }											//sp2和sp3离开作用域,引用计数减2,变为1 
    
    int main()
    {
    	auto p = init();						//此处赋值的拷贝与return处的拷贝是一致的 
    	cout << p.use_count() << endl;			//输出1 
    	return 0;
    }
    

    由代码证实,函数结束时,引用计数减2,而非减1!

  • 相关阅读:
    Golang 学习入坑(三)Go语言变量及常量及运算符
    Golang 学习入坑(二)Go语言结构及基本语法及基本类型
    docker 理解和一些应用
    golang学习入坑(一)Go介绍及环境搭建
    VMware安装Centos7超详细程
    2020-05-28 postgresql sequence
    2020-05-18 缓存穿透、缓存击穿、缓存雪崩
    2020-05-15 rocketmq-spring-starter支持多集群
    2020-05-15 rocketmq-spring-starter结合disconf使用
    2020-05-14 RSA加解密
  • 原文地址:https://www.cnblogs.com/xzxl/p/7852597.html
Copyright © 2011-2022 走看看