• 【C++11】shared_ptr智能指针使用详解


    系列文章目录

    【C++11】智能指针与动态内存



    简介

    shared_ptr 是一个类的模板,它使用引用计数的方式来管理一个动态分配的内存资源。shared_ptr 需要一个动态分配的对象时,会在堆上分配一块内存来存储该对象,并维护一个引用计数。

    shared_ptr允许多个shared_ptr指向同一个对象,通过引用计数来跟踪有多少个shared_ptr指向同一个对象。每次创建一个新的shared_ptr指向同一个对象时,引用计数增加1。当一个shared_ptr离开作用域或被重置时,引用计数减少1。当引用计数变为0时,shared_ptr会自动删除所指向的对象并释放内存。


    一、头文件

    本文出现的关于shared_ptr的方法都包含在此头文件中

    #include 
    
    • 1

    二、初始化

    1. make_shared

    最安全方法是调用make_shared的标准库函数。同时引用计数从0到1。

    // 指向一个值为默认值的int的shared_ptr:0
    std::shared_ptr<int> p1 = make_shared<int>();
    // 指向一个值为4的int的shared_ptr
    std::shared_ptr<int> pt2 = make_shared<int>(4);
    // 指向一个值为"555555"的string的shared_ptr
    std::shared_ptr<std::string> p3= make_shared<string>(6, '5');
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    通常用定义一个auto对象来保存make_shared结果

    // 指向一个值为默认值的int的shared_ptr:0
    auto p4 = make_shared<int>();
    
    • 1
    • 2

    2. 拷贝和赋值

    通过拷贝和赋值也可以初始化。

    auto p = make_shared<int>(4);   // p指向的引用对象只有p一个引用者,此对象引用计数为1
    auto q(p);                      // p和q指向的相同对象,此对象引用计数递增变为2
    
    auto r = make_shared<int>(4);   // r指向的引用对象只有r一个引用者,引用计数为1
    auto r = q;                     // 给r赋值,令它指向另一个地址
                                    // 递增q指向的对象的引用计数,此对象引用计数变为3
                                    // 递减r原来指向的对象的引用计数,此引用计数变为0,自动释放
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    三、实例

    #include 
    #include    // for std::shared_ptr and std::unique_ptr  
    
    class Person
    {
    public:
    	Person(std::string name, int age) :m_name(name), m_age(age)
    	{
    		std::cout << "Create Person" << " " << m_name.c_str() << " " << m_age << std::endl;
    	};
    	~Person()
    	{
    		std::cout << "Destroy Person" << " " << m_name.c_str() << " " << m_age << std::endl;
    	};
    
    private:
    	std::string m_name;
    	int m_age;
    };
    
    int main()
    {
        // 离开作用域场合
    	{
    
    		// 创建shared_ptr
    		std::shared_ptr<Person> sharedPtr = std::make_shared<Person>("Tom", 10);
    		// 输出引用计数( 结果:1)
    		std::cout << "SharedPtr uses" << " " << sharedPtr.use_count() << std::endl;
    		{
    			// sharedPtr2和sharedPtr指向同一个对象,此对象的引用计数递增,变为2
    			std::shared_ptr<Person> sharedPtr2 = sharedPtr;   // sharedPtr2不会调用构造函数,因为这个指针和sharedPtr指向的是同一个内存地址
    			// 输出引用计数( 结果:2)
    			std::cout << "SharedPtr uses" << " " << sharedPtr.use_count() << std::endl;
    		}
    		
    		// 当sharedPtr2离开作用域时,其指向对象的引用计数递减,变为1(此时还有sharedPtr指向该对象)。 
    		std::cout << "SharedPtr uses" << " " << sharedPtr.use_count() << std::endl;
    	}
    	// 当sharedPtr离开作用域时,引用计数递减变为0。然后析构函数自动被调用,析构函数会检查 shared_ptr 的引用计数,如果计数为 0,则调用 reset 函数来释放对象(不用显示调用),并将指针设为null。
    	
    	std::cout << "Hello World!\n";
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
  • 相关阅读:
    长文多图一步步讲清楚:DDD理论、建模与代码实现全流程
    这个锂电池保护方案来自TIDA-010030
    企业工程项目管理系统源码+spring cloud +spring boot+项目模块功能清单
    Codeforces Round #823 (Div. 2) A-D
    【大数据】Apache Iceberg 概述和源代码的构建
    netty+springboot+vue聊天室(需要了解netty)
    跟艾文学编程《Python数据可视化》(02)pyecharts数据可视化
    Java高级技术探索:深入理解JVM内存分区与GC机制
    redis的使用场景
    【力扣1464】数组中两元素的最大乘积
  • 原文地址:https://blog.csdn.net/xiaofeizai1116/article/details/134389256