【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,就必须用智能指针(或者有明确的手动释放逻辑,但不推荐)。
其他情况(栈对象、全局对象、系统管理的对象)不需要用。

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

梁同学与Android

你的鼓励将是我创作的最大动力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值