不能。智能指针仅解决内存释放责任问题,不能无脑替代原始指针;unique_ptr适用于独占场景但须用make_unique保证异常安全;shared_ptr有性能开销和循环引用风险,需weak_ptr破环;裸指针在c交互、数据结构、指针运算等底层场景不可替代。

不能。智能指针不是万能胶,它解决的是「谁该负责释放内存」这个核心问题,但不等于所有原始指针场景都能无脑替换。
std::unique_ptr 能覆盖 90% 的独占所有权场景
绝大多数 new 出来、只归一个对象或作用域管理的资源,std::unique_ptr 是首选。它零拷贝开销、移动语义清晰、析构即释放,比裸指针更安全,性能几乎无损。
- 常见错误:直接用
new构造后传给unique_ptr,却忘了用std::make_unique—— 这会导致异常安全风险(例如构造参数里抛异常时,new已执行但unique_ptr未接管) - 正确写法优先用
std::make_unique<t>(args...)</t>,而不是std::unique_ptr<t>(new T(args...))</t> - 容器中存
unique_ptr没问题,但别试图对它做std::vector::resize()后再访问已 move 走的元素——此时对应unique_ptr已为nullptr,解引用会 crash
shared_ptr 不是“通用替代品”,滥用反而引入隐性开销和循环引用
std::shared_ptr 的引用计数是原子操作,在多线程下有同步成本;每次拷贝/赋值都触发计数增减;更致命的是,它无法自动破环。
- 典型陷阱:两个
shared_ptr相互持有(比如父子节点、观察者模式中的回调),导致计数永不归零,对象泄漏 - 修复必须显式引入
std::weak_ptr打断循环,且访问前必须调用lock()判断是否还有效 - 不要只为“方便共享”就默认用
shared_ptr——如果只是临时读取、不延长生命周期,裸指针或引用更轻量、语义更明确
原始指针仍有不可替代的底层角色
裸指针没被废弃,是因为它在特定边界上仍是必要工具:
- 与 C API 交互时,函数签名要求
int*或void*,你不能把shared_ptr直接塞进去——得用.get()提取裸地址,但此时你得自己保证该地址在 C 函数返回前有效 - 实现高性能数据结构(如跳表、红黑树节点)时,节点间指针必须是裸指针——智能指针的额外字段和析构逻辑会破坏内存布局和缓存局部性
- 数组遍历、指针算术(
ptr + i)、reinterpret_cast等底层操作,裸指针是唯一合法选择
真正容易被忽略的点不是“能不能换”,而是“换完之后所有权是否清晰”。很多 bug 来自把 shared_ptr 当成普通变量传进函数,结果函数内部又转手给了另一个长期存活的对象,而调用方完全不知情——这时裸指针反而强迫你写注释说明“此指针仅借用,不转移所有权”。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











