GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • 卡码笔记-最强八股文
  • 计算机基础
  • Python
  • C++
  • Java
  • Go
  • ChatGPT充值
  • Claude充值
  • 国内使用Claude
  • 中转站推荐
  • 🔥大模型🔥
  • 大模型面经
  • Java面经
  • C++面经

This view

  • Original page
  • New address

GeezerVison is showing notes.kamacoder.com — C++智能指针uniqueptr、sharedptr、weak_ptr核心区别与选型:RAII所有权语义、循环引用解决方案

# C++智能指针的区别与选型

面试官问"C++ 有哪几种智能指针,区别是什么",大多数人能列出三个名字,但追问"什么时候该用 unique_ptr、什么时候该用 shared_ptr"就答不清楚了。这道题考的不是背定义,而是你对所有权语义的理解深度。

# 简要回答

三种智能指针本质上对应三种所有权模型:unique_ptr 独占(同一时刻只有一个拥有者)、shared_ptr 共享(多个拥有者通过引用计数协调)、weak_ptr 观察(不参与所有权,只是"看一眼还在不在")。选型的核心原则是:能用 unique_ptr 就不用 shared_ptr,需要打破循环引用才用 weak_ptr。

# 详细回答

智能指针的底层思想是 RAII——把资源的生命周期绑定到对象的生命周期上,构造时获取资源,析构时自动释放,彻底消灭手动 delete 带来的泄漏风险。

unique_ptr — 独占所有权

同一时刻只有一个 unique_ptr 拥有资源。禁止拷贝,只能移动(std::move)。析构时直接 delete,零开销,性能和裸指针一样。90% 的场景应该优先用它——函数内部的局部资源、类的成员变量、工厂函数的返回值,都适合 unique_ptr。

shared_ptr — 共享所有权

多个 shared_ptr 可以指向同一个对象,内部通过引用计数管理生命周期。最后一个 shared_ptr 析构时释放资源。代价是每次拷贝/析构都要原子操作引用计数,比 unique_ptr 重。只有在确实需要多个拥有者的场景才用——比如缓存、观察者模式中的共享资源。

weak_ptr — 弱引用/观察者

不增加引用计数,不参与生命周期管理。通过 lock() 尝试提升为 shared_ptr,如果对象已死就返回空。唯一用途:打破 shared_ptr 的循环引用,或者在不确定对象是否还活着时安全地"探测"一下。

选型决策很简单:默认用 unique_ptr;如果资源确实需要被多处共享,用 shared_ptr;如果出现了循环引用或者需要非拥有性观察,用 weak_ptr。

智能指针选型对比

# 知识拓展

Q:为什么说 unique_ptr 是零开销的?

因为它内部就是一个裸指针,没有引用计数、没有控制块、没有原子操作。编译器优化后,unique_ptr 和裸指针生成的机器码完全一样。

Q:shared_ptr 的性能代价具体在哪?

两方面:一是多了一个控制块的堆分配(用 make_shared 可以合并为一次分配);二是每次拷贝和析构都要做原子加减操作,在高并发场景下这个开销不可忽视。

Q:循环引用是怎么发生的?

A 持有 shared_ptr 指向 B,B 也持有 shared_ptr 指向 A。两者的引用计数永远不会归零,内存永远不会释放。解决办法是把其中一方改成 weak_ptr——weak_ptr 不增加引用计数,打破了循环。

Q:能不能用 unique_ptr 代替 shared_ptr?

如果你能把所有权链条理清楚(谁创建、谁拥有、谁负责销毁),绝大多数场景都可以用 unique_ptr。shared_ptr 往往是"懒得想所有权"的妥协方案,用多了反而容易引入循环引用和性能问题。

← C++中的协程概念及实现 智能指针的实现原理是什么? →

评论

验证登录状态...

You are visitor 01402503 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.