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

【C++】什么是智能指针及应用

在 C++ 项目中,智能指针是管理动态内存的重要工具,能有效避免内存泄漏。Android Framework 中大量使用了自定义的智能指针(sp/wp),标准库的std::shared_ptr和std::unique_ptr也在很多场景中应用。


判断什么时候用智能指针很简单,核心就看谁来负责释放内存。手动管理内存容易出错(比如忘记释放、重复释放),智能指针的作用就是自动帮你释放内存,避免这些问题。

用一个生活例子类比:

  • 手动管理内存 = 你自己租房,到期必须记得退租,否则会罚款(内存泄漏);退错房(重复释放)也会出问题。
  • 智能指针 = 找了个管家,到期自动退租,你不用操心。

一、必须用智能指针的 3 种场景

1. 动态分配的内存(用new创建的对象)

只要你用了new,就必须考虑释放。这时用智能指针最安全。

// 错误示例:手动管理容易忘释放
void func() {int* p = new int(10);  // 分配内存// ... 中间代码如果 return 或抛异常,下面的 delete 不会执行,导致内存泄漏delete p;  // 手动释放,风险高
}// 正确示例:用智能指针自动释放
void func() {std::unique_ptr<int> p(new int(10));  // 分配后交给智能指针// ... 无论中间发生什么,出了作用域自动释放
}
2. 内存需要在多个地方共享

比如一个对象需要被多个函数或类同时使用,用std::shared_ptr可以自动跟踪 “谁还在用”,最后一个使用者用完才释放。

// 场景:一张图片被多个UI组件显示
class Image {
public:Image(const std::string& path) { /* 加载图片 */ }
};void showInWindowA(std::shared_ptr<Image> img) { /* 显示图片 */ }
void showInWindowB(std::shared_ptr<Image> img) { /* 显示图片 */ }int main() {auto img = std::make_shared<Image>("photo.jpg");  // 共享指针showInWindowA(img);  // 传递共享指针(引用计数+1)showInWindowB(img);  // 传递共享指针(引用计数+1)// 当所有地方都不用img了,自动释放图片内存
}
3. 函数需要返回动态分配的对象

如果函数返回new出来的对象,用智能指针可以避免调用者忘记释放。

// 错误示例:返回裸指针,调用者可能忘释放
Image* createImage() {return new Image("pic.jpg");  // 谁来delete?不知道
}// 正确示例:返回智能指针,自动管理
std::unique_ptr<Image> createImage() {return std::make_unique<Image>("pic.jpg");  // 调用者不用管释放
}

二、不需要用智能指针的 3 种场景

1. 栈上的对象(不用new创建的)

栈上的对象会自动销毁,不需要智能指针。

void func() {int a = 10;  // 栈上变量,出作用域自动消失Image img("pic.jpg");  // 栈上对象,出作用域自动调用析构函数// 不需要任何指针管理
}
2. 全局 / 静态变量

全局变量在程序结束时自动释放,静态变量在作用域结束时自动释放。

Image g_globalImg("global.jpg");  // 全局对象,程序结束时自动销毁void func() {static Image s_staticImg("static.jpg");  // 静态对象,函数第一次调用时创建,程序结束时销毁
}
3. 已经由其他系统管理的内存

比如 Android Framework 中,有些对象由系统服务(如Binder)管理生命周期,这时不需要用智能指针。

// 示例:Android中获取系统服务(服务生命周期由系统管理)
sp<IServiceManager> sm = defaultServiceManager();  // 系统提供的智能指针
sp<IBinder> binder = sm->getService(String16("media.player"));  // 系统管理的对象
// 这里的sp是Android自定义智能指针,但原理和std::shared_ptr一样

总结:一句话判断

只要你写了new,就必须用智能指针(或者有明确的手动释放逻辑,但不推荐)。
其他情况(栈对象、全局对象、系统管理的对象)不需要用。

智能指针的核心价值就是:代替人来记着释放内存,减少 “忘记释放” 或 “重复释放” 的低级错误,尤其在复杂项目中能大幅提升代码安全性。

http://www.xdnf.cn/news/19702.html

相关文章:

  • 六大关键步骤:用MES系统重构生产计划管理闭环
  • 从能耗黑洞到精准智控:ASCB2智慧空开重构高校宿舍用电能效模型
  • 均值滤波和中值滤波的简介、C语言实现和实测
  • Adobe Photoshop 2025 最新下载安装教程,附PS2025下载
  • 【项目】多模态RAG必备神器—olmOCR重塑PDF文本提取格局
  • 智慧水利系统解决方案-水利信息化平台
  • linux连接服务器sftp无法输入中文
  • 直播预告 | Excelize 跨语言实战
  • 代码随想录二刷之“回溯”~GO
  • Linux系统中yum包管理器安装软件时遇到的网络连接问题
  • 线上API接口响应慢?一套高效排查与定位问题的心法
  • 【frontend】w3c的发展历史ToDo
  • 基于Springboot + vue3实现的时尚美妆电商网站
  • MySQL 之索引的结构、分类与语法
  • 四个典型框架对比
  • 在 Unity 中调用腾讯云机器翻译
  • 一个好的智能体框架应该是什么样子
  • Activiti流程引擎的用户体系与MIS系统的用户体系打通
  • 一、Git与Gitee常见问题解答
  • 深度学习跨领域应用探索:从技术落地到行业变革
  • pcl案例2 叶片与根茎的分离step2
  • MyBatis 性能优化最佳实践:从 SQL 到连接池的全面调优指南
  • Java网络编程基础 Socket通信入门指南
  • 机器视觉软件--VisionPro、Visual Master,Halcon 和 OpenCV 的学习路线
  • 从零开始学习n8n-定时器+HTTP+飞书多维表格(上)
  • UFUNCTION C++ 的再次理解
  • 产品月报|睿本云8月产品功能迭代
  • AWS:AssumeRole背后真正的安全哲学,不仅是迂回
  • 综合实验:DHCP、VLAN、NAT、BDF、策略路由等
  • K8S 知识框架和命令操作