zoukankan      html  css  js  c++  java
  • C++智能指针,RAII(资源获取即初始化) 原则

    转载:C++ RAII机制详解

    转载:C++share_ptr智能指针的使用

    中文标准库:RAII

    一、unique_ptr

    中文标准库:unique_ptr

    尽量使用unique_ptr替代裸指针

    一个unique_ptr独享它指向的对象,不能直接(使用reset才可以)将一个unique_ptr赋值给其他变量,不过shared_ptr可以。也就是说,同时只有一个unique_ptr指向同一个对象,当这个unique_ptr被销毁时,指向的对象也随即被销毁。如果一个类中包含unique_ptr,那么该类也不能使用拷贝和赋值。

    数组版本

    std::unique_ptr<int[]> ptr = std::make_unique<int[]>(5); //相当于 int ptr[5] = {0};
    

    局部智能指针不能作为函数返回值,因为智能指针的作用域有限

    指针

    1. 获取裸指针 get()

    返回指向被管理对象的指针

    2. 替换被管理对象 reset()

    注意:因为一个unique_ptr独享它指向的对象,因此替换被管理的对象时必须释放之前对象的所有权

    std::unique_ptr<int> p1 = std::make_unique<int>(2);
    std::unique_ptr<int> p2 = std::make_unique<int>(3);
    p1 = p2;//错误
    p1.reset(p2); //错误
    p1.reset(p2.release()); //正确,此时p1管理的是大小为3的int数组对象
    

    3. 释放被管理对象 release()

    unique_ptr被销毁时(如离开作用域),对象也就自动释放了,也可以通过其他方式下显式释放对象。如:

    up = nullptr; //置为空,释放up指向的对象
    up.release(); //放弃控制权,返回裸指针,并将up置为空
    up.reset();   //释放up指向的对象
    

    二、share_ptr

    尽量少用share_ptr

    shared_ptr是支持共享所有权的引用计数型指针,“共享”指的是允许多个指针指向同一个资源,shared_ptr对象可以被拷贝与赋值,“引用计数”指的是它可以记录当前指向同一资源的指针的数量, 当计数为0的时候才会释放动态分配的对象。对shared_ptr循环引用会导致因为无法释放资源引发的内存泄漏。典型的如双链表。不要把一个裸指针给多个shared_ptr对象管理

    三、weak_ptr

    weak_ptr就是为了辅助shared_ptr的,它本身不能直接指向原生指针对象,只能指向shared_ptr对象。

    weak_ptr总结

    • weak_ptr虽然是一个模板类,但是不能用来直接定义指向原始指针的对象。

    • weak_ptr接受shared_ptr类型的变量赋值,但是反过来是行不通的,需要使用lock函数。

    • weak_ptr设计之初就是为了服务于shared_ptr的,所以不增加引用计数就是它的核心功能。

    • 由于不知道干了什么之后weak_ptr所指向的对象就会被析构掉,所以使用之前请先使用expired函数检测一下。

    转载:智能指针(3):weak_ptr浅析

    四、auto_ptr

    被摒弃 https://www.cnblogs.com/lanxuezaipiao/p/4132096.html

    示例代码

    点击查看代码
    #include <iostream>
    #include <memory>
    
    class A
    {
    public:
    	std::shared_ptr<int> sharedInt = std::make_shared<int>(1);
    	//std::unique_ptr<int> uniqueInt = std::make_unique<int>(2);
    	void show() { std::cout << *sharedInt << "
    "; }
    };
    
    int main()
    {
    	A a;
    	a.show();
    	A a1 = a;  //如果类A中有unique_ptr报错
    	A a2 = a1;
    
    	std::cout << a.sharedInt.use_count();  //3
    
    	///< Shared_ptr
    	auto s1 = std::make_shared<int>(1);
    	auto s2 = std::make_shared<int>(2);
    	auto s3 = std::make_shared<int>(3);
    
    	std::shared_ptr<int> ps1;
    	std::shared_ptr<int> ps2;
    	auto c1 = s1.use_count(); //1
    	auto c2 = s2.use_count(); //1
    	auto c3 = s3.use_count(); //1
    	auto c4 = ps1.use_count(); //0
    	auto c5 = ps2.use_count(); //0
    
    	ps1 = s1;  //共享s1指向的对象(unique_ptr不支持)
    	auto c6 = ps1.use_count(); //2
    	auto c7 = s1.use_count(); //2
    	ps2 = s1;
    	auto c8 = s1.use_count(); //3
    	auto c9 = ps2.use_count(); //3
    
    
    	///< unique_ptr
    	std::unique_ptr<int> pu1 = std::make_unique<int>(2);
    	std::unique_ptr<int> pu2 = std::make_unique<int>(3);
    	//p1.reset(p2); //错误
    	//std::unique_ptr<int> pu6 = pu1; //错误,因为unique_ptr独享它指向的对象(可以用shared_ptr共享)
    	pu1.reset(pu2.release()); //正确,此时p1管理的是值为3的int指针
    
    	auto pu1Value1 = *pu1.get();
    
    	std::unique_ptr<int[]> pu3 = std::make_unique<int[]>(9);  //大小为9的int数组
    	std::unique_ptr<int[]> pu4 = std::unique_ptr<int[]>(new int[3]); //大小为3的int数组,不推荐使用new
    
    	std::unique_ptr<int[]> pu5;
    
    	int arr[5] = { 0 };
    	int* pu6 = new int[8];
    	pu4.reset(arr);
    	pu5.reset(pu6);
    
    	//std::unique_ptr<int[]> pu7(pu3);  //错误
    	std::unique_ptr<int[]> pu7(std::move(pu3));//正确
    
    	//pu5.reset(std::move(pu3));  //错误
    	//pu4.reset(pu3); //错误
    	pu5.reset(pu3.release()); //正确
    	
    	(*pu1) = 99;  //给pu1赋值
    	auto pu1Value2 = *pu1;
    
    
    	system("pause");
    	return 0;
    }
    
  • 相关阅读:
    实现FTP断点续传
    系统软件自动部署实现方案
    QT实现多语言切换
    QTreeWidget实现动态加载本地文件系统
    QuaZip实现多文件打包
    FileZilla命令行实现文件上传以及CreateProcess实现静默调用
    ctkPlugin插件系统实现项目插件式开发
    Windows与Linux下文件操作监控的实现
    QT皮肤系统的动态切换
    OpenGL 学习
  • 原文地址:https://www.cnblogs.com/mmmmmmmmm/p/14512823.html
Copyright © 2011-2022 走看看