当前位置: 首页 > news >正文

C++新特性—— 智能指针(shared_ptr/unique_ptr/weak_ptr)

C++11引入了智能指针,用于自动管理动态内存的释放,避免内存泄漏。常用的智能指针有 unique_ptrshared_ptrweak_ptr,每种类型的智能指针有不同的特点和使用场景。

头文件为<memory>

1. unique_ptr 智能指针

unique_ptr 是独占指针,即某个动态分配的内存只能被一个 unique_ptr 所拥有,不支持拷贝和赋值操作。它会在超出作用域时自动释放资源。

示例代码:

#include <iostream>
#include <memory>using namespace std;int main()
{unique_ptr<int> p1(new int(24));cout << "*p1 = " << *p1 << endl << endl;unique_ptr<int> p2 = move(p1); // 使用 move 转移所有权cout << "*p2 = " << *p2 << endl << endl;p2.reset(); // 显式释放内存p1.reset(); unique_ptr<int> p3(new int(250));p3.reset(new int(666)); // 绑定动态对象cout << "*p3 = " << *p3 << endl << endl;p3 = nullptr; // 显式销毁指向的对象,同时智能指针变为空,等价于 p3.reset()unique_ptr<int> p4(new int(999));int* p = p4.release(); // 释放控制权,内存不释放cout << "*p = " << *p << endl << endl;// p4 已经没有管理任何对象,访问会导致错误// cout << "*p4 = " << *p4 << endl;delete p; // 手动释放内存return 0;
}

输出结果:

*p1 = 24*p2 = 24*p3 = 666*p = 999

关键点:

  • unique_ptr 不能拷贝,只能通过 std::move 转移所有权。

  • reset() 用来释放智能指针管理的内存,release() 用来转移控制权但不释放内存。


2. shared_ptr 智能指针

shared_ptr 是共享指针,多个 shared_ptr 可以指向同一块动态内存,并通过引用计数的方式管理内存的生命周期。引用计数为零时,资源会被释放。

shared_ptr 的核心是一个叫 控制块(control block) 的结构体,它记录了以下两个关键信息:

  1. 指向资源的原始指针(void *ptr

  2. 引用计数(ref_count)

可以把它想象成这样(伪结构体):

struct ControlBlock {int ref_count; // 当前有多少 shared_ptr 指向这块内存void* ptr;     // 指向实际数据的指针
};

示例代码:

#include <iostream>
#include <memory>
using namespace std;int main()
{shared_ptr<int> p1(new int(456));shared_ptr<int> p2 = p1; // 共享所有权cout << "p2 引用计数: " << p2.use_count() << endl << endl;cout << "*p1 = " << *p1 << endl;cout << "*p2 = " << *p2 << endl;cout << "p2 引用计数: " << p2.use_count() << endl << endl;p1.reset(); // p1 不再管理内存cout << "p2 引用计数: " << p2.use_count() << endl << endl;return 0;
}

代码解释:

  • 每个 shared_ptr 都会共享同一个“引用计数控制块”。

  • 当新的 shared_ptr 被复制时,引用计数 +1;

  • 当某个 shared_ptr 调用 reset() 或超出作用域时,引用计数 -1;

  • 当引用计数减为 0 时,内存会被自动释放。

输出结果:

p2 引用计数: 2*p1 = 456
*p2 = 456
p2 引用计数: 2p2 引用计数: 1

关键点:

  • shared_ptr 会自动管理内存,通过引用计数来确保内存安全。

  • use_count() 用来获取当前对象的引用计数。

  • reset() 用来重置 shared_ptr,使其释放控制的内存。


3. make_shared 函数

make_shared 是创建 shared_ptr 的推荐方法,它通过单次内存分配实现了更高效的内存管理。它不仅分配内存给对象,还分配了用于引用计数的内存。

示例:

auto p = make_shared<int>(10);

shared_ptr(new int(10)) 的区别在于:

  • make_shared 会一次性分配内存,效率更高。

        例如:

  (1)shared_ptr

shared_ptr<int> p1(new int(10));

        这里是创建一个 shared_ptr,同时通过 new 操作符分配了一个 int 类型的动态内存。这样,shared_ptr 管理的是一个指向动态内存的原始指针。首先,new int(10) 分配了内存给 int 类型的对象,然后 shared_ptr 会为引用计数分配内存。因此总共进行了 两次内存分配:一次是为对象本身分配内存(即 int 类型的内存),一次是为 shared_ptr 维护的引用计数分配内存             

  (2)make_shared

auto p2 = make_shared<int>(10);

        使用 make_shared,它会一次性分配内存,同时为对象本身和引用计数分配内存。即,make_shared 只需要 一次内存分配,同时包含了对象和引用计数的信息。

  • 它避免了内存泄漏的风险,特别是在异常情况下。

4. weak_ptr 智能指针

weak_ptr 是辅助 shared_ptr 使用的智能指针,它不增加或减少引用计数,因此它并不拥有资源的所有权。weak_ptr 不能直接访问资源,但可以通过 lock() 方法将其转化为 shared_ptr 进行访问。

示例代码:

#include <iostream>
#include <memory>
using namespace std;int main()
{shared_ptr<int> p1(new int(300));shared_ptr<int> p2 = p1;weak_ptr<int> wp = p1; // weak_ptr 不增加引用计数cout << "wp 引用计数: " << wp.use_count() << endl << endl;cout << "*p1 = " << *p1 << endl;cout << "*p2 = " << *p2 << endl;cout << endl;return 0;
}

输出结果:

wp 引用计数: 2*p1 = 300
*p2 = 300

关键点:

  • weak_ptr 不拥有资源的所有权,不能直接使用资源。

  • 使用 lock() 方法可以获得一个 shared_ptr,从而访问资源。


5.总结

  • unique_ptr:独占资源,无法拷贝或赋值,适用于资源的独占管理。

  • shared_ptr:共享资源,通过引用计数管理内存,适用于多个对象需要共享同一资源的场景。

  • weak_ptr:辅助 shared_ptr,不增加引用计数,避免循环引用,适用于观察者模式等场景。

http://www.dtcms.com/a/532254.html

相关文章:

  • OpenCV(十四):绘制直线
  • 支持支付宝登录的网站建设wordpress指定分类文章列表
  • Halcon卡尺 Measure_pos原理与实现(C++ 和Python版本,基于OpenCV)
  • 在线课程网站开发任务书邢台 网站建设
  • 专业做英文网站如何看出一个网站优化的是否好
  • PostgreSQL事务隔离级别详解
  • 从底层逻辑到实战落地:服务端与客户端负载均衡器的深度拆解
  • 笔试强训(十三)
  • 基于罗伊适应模型的产后抑郁家庭护理干预研究综述​
  • Bright Data 抓取浏览器API实战:助力高效完成定向大规模数据稳定采集
  • 合肥市做效果图的网站最适合新人的写作网站
  • 关于做视频网站的一些代码南京网站制作公司怎么样
  • 6分钟制作TikTok游戏领域热门短视频分析AI Agent
  • 自由通讯的魔法:Go从零实现UDP/P2P 聊天工具
  • Cortex-M3-STM32F1 开发:(十二)HAL 库开发 ➤ SysTick 系统滴答定时器
  • go-ethereum core之以太网虚拟机EVM
  • 自己怎么免费做网站网站开发 合同
  • 网站如何做脚注一般使用的分辨率的显示密度是多少dpi )
  • 嵌入式开发中ln命令使用指南
  • C++模板进阶及特化实战指南
  • zenm自己做网站淮北建设网
  • 网站title keyword descriptionwordpress 分类筛选
  • 网站系统设计目标企业融资方案范本
  • 《AI 应用层革命(二)——从应用到生态:当智能体开始重塑世界》
  • 使用 Python 元类与属性实现惰性加载:Effective Python 第47条
  • 环广西世巡赛开战!维乐Senso Prime 坐垫助你竞速
  • DeepSeek讲“南辕北辙”者的志向
  • 做网站在线视频如何添加湘潭网站seo
  • 智能文本抽取:通过OCR、自然语言处理等多项技术,将非结构化文档转化为可读、可分析的数据资产
  • 许昌哪个网站做苗木网站建设怎么让百度搜索到