• C++11 智能指针 已完成未发布


    1. 智能指针种类

    • std::shared_ptr: 共享智能指针,内部使用引用计数管理
    • std::unique_ptr: 独占智能指针,必须使用move进行管理权限移交
    • std::weak_ptr:弱引用智能指针,是用来辅助shared_ptr的,主要角色是一个监视者,它的构造与析构并不会影响shared_ptr的引用计数(不能进行指针共享及资源操作)

    1.1 shared_ptr初始化

    • 构造函数 std::shared_ptr 变量名(被管理的内存对象)std::shared_ptr 变量名(std::move(被管理的内存对象))使用move时引用计数不会被加1
    • std::make_shared函数,
    • std::shared_ptr::reset方法有两个作用,第一是断开智能指针对对内存的管理(即引用计数减一),另外一个作用就是还可以将被断开的智能指针,设置到另一块内存(管理另一块内存)

    shared_ptr 是一个模板类,shared_ptr可以实现多个智能指针管理同一块内存(内部通过引用计数实现)。可以使用use_count()查看当前有多少个智能指针在管理当前内存。

    #include 
    #include 
    using namespace std;
    
    int main() {
    		// 通过构造函数初始化,并初始化为3
    	shared_ptr<int> pint(new int(3));
    	cout << "pint use_count" << pint.use_count() << endl;
    
    	// 通过移动构造函数初始化
    	shared_ptr<int> pint_move = move(pint);
    	cout << "pint use_count" << pint.use_count() << endl;
    	cout << "pint_move use_count" << pint_move.use_count() << endl;
    
    	// 通过拷贝构造函数初始化
    	shared_ptr<int> pint_copy = pint_move;
    	cout << "pint_copy use_count" << pint_copy.use_count() << endl;
    	cout << "pint use_count" << pint.use_count() << endl;
    
    	// 通过std::make_shared 初始化
    	shared_ptr<int> pint_make_shared = make_shared<int>(3);
    	cout << "pint_make_shared use_count" << pint_make_shared.use_count() << endl;
    
    	// 通过reset初始化
    	shared_ptr<int> pint_reset = make_shared<int>(3);
    	pint_reset.reset();
    	cout << "pint_reset use_count" << pint_reset.use_count() << endl;
    
    	pint_reset.reset(new int(5));
    	cout << "pint_reset use_count" << pint_reset.use_count() << endl;
    
    	// 获取原始指针
    	pint_make_shared.get();
    	return 1 ;
    }
    
    • 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

    1.2 unique_ptr初始化

    • 构造函数初始化: unique_ptr ptr1(new int(520))
    • 移动构造函数: move()
    • reset()方式初始化
    • make_unique()方式初始化
    	// 构造函数初始化
    	unique_ptr<int> p1(new int(10));
    	
    	// 移动构造
    	unique_ptr<int> p2 = move(p1);
    
    	// reset() 初始化
    	p2.reset(new int(11));
    
    	// make_unique初始化
    	unique_ptr<int> p3 = make_unique<int>(12);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    1.3 weak_ptr初始化

    • 默认构造函数:
    • 拷贝构造函数
    	shared_ptr<int> pint(new int(5));
    
    	// 构造函数初始化
    	weak_ptr<int> wp;
    	weak_ptr<int> wp1(wp); // 此时wp和wp1都是空的weak_ptr对象
    	weak_ptr<int> wp2(pint);
    
    	// 拷贝构造方式初始化
    	weak_ptr<int> wp3;
    	wp3 = wp2;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    2. 指定删除器

    当智能指针管理的内存被释放的时候,这块内存会被智能指针析构。可以在智能指针初始化的时候指定这个方法(本质是个回调函数)。管理数组的时候使用,否则无法被默认的删除器删除。

    2.1 shared_ptr删除器

    	shared_ptr<int> pint(new int(3), [](int* p) {
    		delete p;
    	});
    	shared_ptr<int> pint2(new int(3), default_delete<int>());
    
    	// 管理数组
    	shared_ptr<int> pint_arr1(new int[10], [](int p[]) {delete[] p;});
    
    	// 使用默认的删除器对数组内存管理释放管理
    	shared_ptr<int> pint_arr2(new int[10], default_delete<int[]>());
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    2.2 unique_ptr删除器

    	// 与共享指针不一样的是,独占指针的删除器需要在模板参数中声明类型
    	unique_ptr<int,function<void(int[])>> p1(new int[10], [=](int p[]) {delete[] p;});
    
    	// 自动释放数组内存,此时需要明确指出管理的数组类型指针
    	unique_ptr<int[]> p2(new int[10]);
    	// 在C++11 中shared_ptr不支持自动释放数组内存,C++11之后才被支持
    	shared_ptr<int[]> p3(new int[10]);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    3. 智能指针注意事项

    3.1 shared_ptr

    • 不能使用一个原始地址初始化多个共享智能指针,会造成double free的情况
    • 函数不能返回管理了this的共享智能指针对象
      class ReturnThis {
      public:
      	shared_ptr<ReturnThis> GetSharedThis() {
      		return shared_ptr<ReturnThis>(this);
      	}
      };
      /* 解决方式 enable_shared_from_this内部是通过weak_ptr实现的,通过weak_ptr的lock()方法返回一个shared_ptr对象
      class ReturnThis : public enable_shared_from_this{
      public:
      	shared_ptr GetSharedThis() {
      		return shared_from_this();
      	}
      };
      */
      int main() {
      
      	ReturnThis* pThis = new ReturnThis();
      	//1. 使用一个原始地址初始化多个共享智能指针,此时造成 double free
      	shared_ptr<ReturnThis> pSharedThis1(pThis);
      	shared_ptr<ReturnThis> pSharedThis2(pThis);
      
      	//2. 此时仍然会造成double free
      	shar ed_ptr<ReturnThis> pSharedThis3 = pSharedThis1->GetSharedThis();
      	return 1 ;
      }
      
      • 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
    • 共享智能指针不能循环引用(a 引用b ,b也引用a)
      class ClassB;
      
      class ClassA {
      public:
      	// shared_ptr m_pClassB;
      	weak_ptr<ClassB> m_pClassB; // 不会增加shared_ptr的引用计数
      	~ClassA()
      	{
      		cout << "ClassA" << endl;
      	}
      };
      
      class ClassB {
      public:
      	shared_ptr<ClassA> m_pClassA;
      	~ClassB()
      	{
      		cout << "ClassB" << endl;
      	}
      };
      
      int main() {
      	shared_ptr<ClassA> pClassA(new ClassA());
      	shared_ptr<ClassB> pClassB(new ClassB());
      	cout << "ClassA use_count:" << pClassA.use_count() << endl;
      	cout << "ClassB use_count:" << pClassB.use_count() << endl;
      
      	pClassA->m_pClassB = pClassB;
      	pClassB->m_pClassA = pClassA;
      	cout << "ClassA use_count:" << pClassA.use_count() << endl;
      	cout << "ClassB use_count:" << pClassB.use_count() << endl;
      
      	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

    欢迎转载QAQ~

  • 相关阅读:
    计算机网络常见概念
    Win:使用 netsh 命令配置 Port Forwarding
    土地利用程度综合指数计算/argis教程
    linux文件组 avc: denied { dac_read_search } for capability=2
    AI智慧安防智能监控平台EasyCVR隔天设备录像播放失败是什么原因?该如何解决?
    Springboot使用AOP
    07 | 自己动手,搭建HTTP实验环境
    【Windows】磁盘管理无法删除卷
    解决Verilog中的generate_for问题,就是生成多个块,其区别于for块。
    rpc error: code = Unimplemented desc =
  • 原文地址:https://blog.csdn.net/weixin_41111116/article/details/120936154