【c++】【智能指针】什么情况下不适合智能指针

【c++】【智能指针】什么情况下不适合智能指针

1. 性能开销

大多数场景下用到的都是 unique_ptr

  • 代表的是专属所有权,即由 unique_ptr 管理的内存,只能被一个对象持有。
  • unique_ptr 不支持复制和赋值
  • unique_ptr 在默认情况下和裸指针的大小是一样的。所以内存上没有任何的额外消耗,性能是最优的

shared_ptr:共享所有权

  • 使用 shared_ptr 之前应该考虑,是否真的需要使用 shared_ptr, 而非 unique_ptr。
  • shared_ptr 代表的是共享所有权,即多个 shared_ptr 可以共享同一块内存。
  • shared_ptr 是支持复制的。
  • shared_ptr性能开销更大,内存占用是裸指针的两倍 。因为除了要管理一个裸指针外,还要维护一个引用计数。
    因此相比于 unique_ptr, shared_ptr 的内存占用更高

std::shared_ptr 的引用计数机制 会引入额外的性能开销,
std::unique_ptr 性能更接近裸指针,但在某些场景下仍存在额外的构造、析构或转移开销。


2. 不适合所有场景

  • 智能指针主要管理堆内存,对栈上对象、全局对象或静态对象无效。
  • 对于某些短生命周期的局部变量,栈分配更高效,无需使用智能指针。
cpp 复制代码
void func() {
    int a = 10;  // 栈上对象,生命周期由作用域自动管理,使用智能指针反而增加不必要的开销。
}

3. 循环引用问题

  • std::shared_ptr 存在循环引用的风险,会导致内存泄露。
  • 解决循环引用需要使用 std::weak_ptr,但引入 weak_ptr 也会增加代码复杂度。

示例:循环引用导致的内存泄漏

cpp 复制代码
#include <iostream>
#include <memory>
using namespace std;

struct B;  // 前向声明

struct A {
    shared_ptr<B> ptr;  // A指向B
    ~A() { cout << "A 被销毁" << endl; }
};

struct B {
    shared_ptr<A> ptr;  // B指向A
    ~B() { cout << "B 被销毁" << endl; }
};

int main() {
    auto a = make_shared<A>();
    auto b = make_shared<B>();
    a->ptr = b;
    b->ptr = a;

    // 程序退出时 A 和 B 的析构函数都未调用,发生内存泄漏
    return 0;
}

4. 控制权与灵活性

  • 在某些情况下,使用裸指针更直观 ,尤其当对象的生命周期由其他机制管理时
  • 智能指针默认会在生命周期结束时释放资源,若不小心在非预期时间释放,可能引发程序错误

示例 :部分 C API 要求使用裸指针,如 malloc()free()pthread 等。


5. 兼容性

  • 一些 C++ 库和框架可能不兼容智能指针,需要使用裸指针来适配。

6. 代码的可读性和复杂度

  • 滥用智能指针可能会降低代码的可读性,尤其在复杂的层次结构中,理解 shared_ptr、unique_ptr、weak_ptr 之间的关系可能变得困难。
相关推荐
xiangyun612 分钟前
【408数据结构 06】双链表、循环链表、静态链表
c语言·开发语言·数据结构·c++·算法
白远山1 小时前
家政服务家政社区派单实战:调度系统架构设计与实现指南
java·开发语言·小程序·架构·需求分析
fpcc2 小时前
计算机原理—构建过程中的分段分析
c++
xxwxx__2 小时前
C++ AVL 树深度剖析:平衡二叉搜索树原理、源码与面试考点
数据结构·c++
Escalating_xu2 小时前
【C语言常见概念】从第一行代码到字符串结束标志:一次打通编译、main、ASCII、转义字符与注释
c语言·c++
DevRay2 小时前
Java 21虚拟线程深度实战:告别线程池焦虑,百万并发吞吐量直接翻倍(原理+代码+避坑)
java·开发语言
bnmoel2 小时前
C++ 基础入门篇(三):内联函数与空指针
c++·内联函数·nullptr·低层
码匠许师傅2 小时前
【C++三方组件】TinyXML2:两个文件的极简 XML 解析器
xml·c++
free-elcmacom2 小时前
C++学习<1>程序分区
开发语言·c++
醉颜凉2 小时前
Java 必看:如何彻底避免 HashMap 多线程死循环问题?
java·开发语言