简易教程: C++的智能指针
2025年5月16日 05:52
C++ 智能指针教程
C++ 中的智能指针提供了自动且安全的内存管理。它们通过 RAII(资源获取即初始化)机制,帮助开发者避免内存泄漏和悬空指针的问题,确保对象在生命周期结束时被正确释放。
本教程将介绍 C++ 中三种主要的智能指针:
std::unique_ptr
:独占式所有权std::shared_ptr
:共享式所有权std::weak_ptr
:非拥有式弱引用
1. std::unique_ptr
unique_ptr
拥有独占所有权。一个资源只能被一个 unique_ptr 拥有。
示例:管理简单对象
#include <iostream> #include <memory> int main() { std::unique_ptr<int> p = std::make_unique<int>(42); std::cout << "值: " << *p << "\n"; // 转移所有权 std::unique_ptr<int> q = std::move(p); if (!p) std::cout << "p 现在是空指针\n"; std::cout << "q 指向: " << *q << "\n"; }
示例:构建链表
struct Node { int val; std::unique_ptr<Node> next; Node(int v) : val(v), next(nullptr) {} }; void printList(const std::unique_ptr<Node>& head) { const Node* curr = head.get(); while (curr) { std::cout << curr->val << " "; curr = curr->next.get(); } std::cout << "\n"; } int main() { auto head = std::make_unique<Node>(1); head->next = std::make_unique<Node>(2); head->next->next = std::make_unique<Node>(3); printList(head); }
2. std::shared_ptr
shared_ptr
允许多个指针共享同一个资源的所有权。它通过引用计数管理资源,当引用数为零时自动释放内存。
示例:共享资源
#include <iostream> #include <memory> int main() { std::shared_ptr<int> a = std::make_shared<int>(100); std::shared_ptr<int> b = a; std::cout << "a 的引用计数: " << a.use_count() << "\n"; std::cout << "b 的引用计数: " << b.use_count() << "\n"; std::cout << "*b = " << *b << "\n"; }
示例:共享链表节点
struct Node { int val; std::shared_ptr<Node> next; Node(int v) : val(v), next(nullptr) {} };
3. std::weak_ptr
weak_ptr
是一种弱引用,不拥有资源,仅用于观察 shared_ptr
所管理的对象。它常用于打破循环引用,防止内存泄漏。
示例:打破循环引用
#include <iostream> #include <memory> struct B; struct A { std::shared_ptr<B> b_ptr; ~A() { std::cout << "A 被销毁\n"; } }; struct B { std::weak_ptr<A> a_ptr; ~B() { std::cout << "B 被销毁\n"; } }; int main() { auto a = std::make_shared<A>(); auto b = std::make_shared<B>(); a->b_ptr = b; b->a_ptr = a; }
是否存在 make_weak?
不存在 std::make_weak
,因为 weak_ptr
不拥有资源,它必须引用一个已存在的 shared_ptr
。
如何创建 weak_ptr
#include <iostream> #include <memory> int main() { std::shared_ptr<int> sp = std::make_shared<int>(42); std::weak_ptr<int> wp = sp; if (auto locked = wp.lock()) { std::cout << "值: " << *locked << "\n"; } else { std::cout << "对象已被释放\n"; } }
总结
智能指针 | 所有权 | 线程安全的引用计数 | 典型用途 |
---|---|---|---|
unique_ptr |
独占 | N/A | 高效、安全的单一所有权 |
shared_ptr |
共享 | 是 | 多个所有者共享资源 |
weak_ptr |
无 | N/A | 打破 shared_ptr 的循环引用 |
C/C++编程
- 简易教程: C++的智能指针
- C++ 编程练习题: 如何合并两个二叉树?
- C++ 编程练习题 - 找出第三大的数
- C++ 编程练习题 - 最多连续的 1
- C++ 编程练习题 - 左子树叶节点之和 (深度优先+广度优先+递归)
- C++ 编程练习题 - 最多水容器 (递归)
- C++的异步编程: std::future, std::async 和 std::promise
- C编程练习题: 翻转整数位
- C++编程练习题: 找出字符串的所有大小小组合
- C/C++ 中的内存管理器(堆与栈)
- C++编程练习题: 对两单向链表求和
英文:Tutorial on C++ Smart Pointers
本文一共 375 个汉字, 你数一下对不对.扫描二维码,分享本文到微信朋友圈
The post 简易教程: C++的智能指针 first appeared on 小赖子的英国生活和资讯.
相关文章:
- 被动收入之: 微博红包 今年开始重新经营我的微博帐号 drlai 收到两笔微信红包,应该是来自于官方的支持,150元(成功提现到支付宝)。虽然这不能持久,也没多少,但毕竟实现了零的突破,意义重大。 如果流量上来,内容创作者可能会接受到比较多的赞赏,这也是一个比较简单的变现方法。这也能作为一种被动收入,不过如果不是头部网红,可能杯水车薪,但如果你有好几个类似这样的,也能积少成多! 在用户中心,微博用户可以每天登陆手机微博APP打卡,获取点数和少量的红包钱(几分钱),积少成多! 微博做些小任务可获得积分和几分钱。聊胜于无。 微博的主要盈利模式 微博的主要盈利模式主要包括以下几个方面: 广告收入:微博的大部分收入来源于广告,尤其是品牌广告和效果广告。广告形式包括信息流广告(类似于推文广告)、热门话题广告、开屏广告和视频广告。品牌和企业可以利用微博庞大的用户群和社交互动来提升曝光率、推广品牌和产品。 会员服务:微博提供的VIP会员服务,用户可以支付订阅费用来享受更多的特权,比如个性化的主题、特有的表情包、私密权限设置等。这些会员服务主要面向个人用户,提升其社交体验。 直播和打赏:微博提供直播平台,用户可以通过购买虚拟礼物来支持主播,微博会从这些打赏中抽取一定比例的分成。此外,微博与内容创作者分成,通过内容付费、知识付费等形式变现。 增值服务:针对企业和大V(拥有大量粉丝的用户),微博还提供增值服务,如账号认证、粉丝数据分析、精准推送、推广和营销工具等。这些服务帮助企业提升营销效果,同时也增加了微博的收入来源。 电商和导流:微博上有大量的电商导流业务,尤其是和明星、网红的合作推广。微博用户在浏览社交内容时,可以直接跳转到商品购买链接,微博通过这种方式赚取导流佣金。 游戏联运:微博也会与一些游戏公司合作推出联合运营的游戏,微博负责推广和流量引入,用户充值或付费时,微博可以获得一部分的分成。 这些模式相结合,使得微博能够在广告市场、内容创作和电商等多个领域获利。...
- Javascript 中 sleep 函数实现 Javascript 中并没有 built-in 的 sleep 函数支持, 在 async/await/Promise 的支持之前, 我们可以用 busy-waiting 的方式来模拟: 1 2 3...
- 换了个奥迪Q5大灯花了我1000英镑 我那辆奥迪Q5 SUV今年年检没通过,原因是左前车灯坏了,需要更换。车厂告诉我,光是订购零件就要700多英镑,加上人工费,总费用得1000英镑。但没办法,如果不修,车辆年检(MOT)就过不了,车也不能上路。 MOT是英国的机动车强制性安全检测(Ministry of Transport Test)的简称。 近侧前位置灯不工作 drl/位置灯集成(4.2.1(a)(ii)) Nearside Front Position lamp not working drl/position...
- C++ 编程练习题: 如何合并两个二叉树? 题意: 合并两个二叉树, 没有说不可以改变原来的二叉树. 合并的时候把结点求合. C/C++ 中二叉树的定义 在C或者C++中, 二叉树的定义可以很方便的用结构体来表征. 其中左右子树都是递归定义. 1 2 3 4 5 6...
- 步步高学生电脑上 Basic 编程语言 peek 用法示例 步步高学生电脑 是8位FC机的经典之作.它上面的BASIC有三个版本 1.0, 2.0 和 2.1 2.1 版本有个在线帮助,实际上是 help.cmd 1.0 是用 Esc 键退回到 DOS 的,...
- 你给SteemIt中文微信群拖后腿了么? 这年头不缺算法, 就缺数据. 这两天花了很多时间在整API上, 整完之后自己用了一下还觉得真是挺方便的. 今天就突然想看一看自己是否给大家拖后腿了, 于是调用每日中文区微信群排行榜单的API, 刷刷拿着 NodeJs 练手: 1 2 3 4 5 6...
- C++ 编程练习题 – 找出第三大的数 题意: 给出一个数组, 求第三大的数字是多少, 重复的数字并不算在内, 比如 第3大的数字是1 而不是 2. Using std::set set 是集合, 是有序的(从小到大), 集合中不包含重复的元素, 所以我们可以遍历数组并把数字添加到集合中....
- 最简单有效的过滤WordPress垃圾评论的方法 当你的Wordpress博客流量大的时候, 不免会收到很多垃圾评论. 本文介绍一种特别简单而且免费的过滤Wordpress垃圾评论的方法. 这种方法不需要你安装任何插件, 也不需要拥有修改Wordpress主题模板函数的能力, 只需要1分钟就可以搞定. 把这个列表拷贝下来 打开 WordPress 的控制面版, 到设置-讨论 拷贝上面的列表到 “评论审核” 或者 “评论黑名单”...