IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> C++ 智能指针总结 -> 正文阅读

[C++知识库]C++ 智能指针总结

C++11 引入了 3智能指针类型:

  • std::unique_ptr<T> :独占资源所有权的指针;
  • std::shared_ptr<T> :共享资源所有权的指针,它的原理是使用引用计数实现对同一块内存的多个引用,在最后一个引用被释放时,指向的内存才释放;
  • std::weak_ptr<T> :共享资源的观察者,需要和 std::shared_ptr 一起使用,不影响资源的生命周期。

1. std::unique_ptr

{
    std::unique_ptr<int> uptr = std::make_unique<int>(200);
    std::unique_ptr<int> uptr1 = uptr;  // 编译错误,std::unique_ptr<T> 是 move-only 的

    std::unique_ptr<int> uptr2 = std::move(uptr); // 转为右值后
    assert(uptr == nullptr);
}

2. std::shared_ptr

{
    std::shared_ptr<int> sptr = std::make_shared<int>(200);
    assert(sptr.use_count() == 1);  // 此时引用计数为 1
    {   
        std::shared_ptr<int> sptr1 = sptr;
        assert(sptr.get() == sptr1.get());
        assert(sptr.use_count() == 2);   // sptr 和 sptr1 共享资源,引用计数为 2
    }   
    assert(sptr.use_count() == 1);   // sptr1 已经释放
}
// use_count 为 0 时自动释放内存
错误用法1:退出{ }p1、p2都会对p0析构,导致p0被删除两次,报错;
{
	int *p0 = new int(1);
    shared_ptr<int> p1(p0);
    shared_ptr<int> p2(p0);
}
错误用法2:循环引用;
struct Father{
    shared_ptr<Son> son_;
};

struct Son{
    shared_ptr<Father> father_;
};

int main(){
    auto father = make_shared<Father>();
    auto son = make_shared<Son>();
    father->son_ = son;
    son->father_ = father;
    return 0;
}

main 函数退出之前,Father_objSon_obj的引用计数都是 2,退出main后,引用计数为1,导致对象没法被销毁,从而引起内存泄漏。

3. std::weak_ptr

std::weak_ptr弱引用指针std::shared_ptr强引用指针),弱引用指针不会增加引用计数。
使用std::weak_ptr修正错误用法2:

struct Father{
    shared_ptr<Son> son_;
};

struct Son{
    weak_ptr<Father> father_;
};

int main(){
    auto father = make_shared<Father>(); // father ptr points to a Father obj
    auto son = make_shared<Son>();

    father->son_ = son;
    son->father_ = father;
    return 0;
}
  1. 退出main之前,Son_obj引用数为2Father_obj引用为1;
  2. 退出main后,son 指针被销毁 ? Son_obj引用数为1;
    ??????father 指针被销毁 ? father_obj引用数为0;
  3. father_obj引用数为0? Father_obj被析构 ? Father_obj.son被销毁? Son_obj引用数为0? Son_obj被析构;
  4. 最终father_objSon_obj被正常析构。
  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-10-31 11:35:34  更:2022-10-31 11:39:48 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/19 7:05:49-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码