c++ shared_ptr与unique_ptr总结

unique_ptr

基本概念

std::unique_ptr<T> 是独占式智能指针:

  • 独占对象所有权,不可拷贝;
  • 可移动(C++11);
  • 离开作用域时自动删除所管理对象;
  • 指针唯一,适合资源严格独占场景。

底层原理

特性:

  • 内部只有一个裸指针 T* ptr;
  • 不需要引用计数
  • 拥有者离开作用域时调用 delete 或自定义 deleter

结构示意:

cpp 复制代码
template<class T, class Deleter = std::default_delete<T>>
class unique_ptr {
private:
    T* ptr;
    Deleter del;
};

删除动作:

cpp 复制代码
~unique_ptr() {
    if (ptr) del(ptr);
}

典型用法

  • 创建

    auto p = std::make_unique<int>(10);

  • 移动所有权

    std::unique_ptr<int> p1 = std::make_unique<int>(5);
    std::unique_ptr<int> p2 = std::move(p1);

  • 自定义删除器

    std::unique_ptr<FILE, decltype(&fclose)> fp(fopen("a.txt","r"), &fclose);

使用场景

std::unique_ptr 的核心是 独占所有权,适合代表"资源严格只有一个拥有者"的场景。

只要不是多个对象共享所有权,就应该优先使用 unique_ptr

它是默认、最安全、性能最佳的智能指针。

示例:unique_ptr 用法

cpp 复制代码
#include <iostream>
#include <memory>

struct Foo {
    Foo()  { std::cout << "Foo()\n"; }
    ~Foo() { std::cout << "~Foo()\n"; }
};

int main() {
    std::unique_ptr<Foo> p1 = std::make_unique<Foo>();

    // 转移所有权
    std::unique_ptr<Foo> p2 = std::move(p1);

    if (!p1) std::cout << "p1 is null\n";
}

输出:

复制代码
Foo()
p1 is null
~Foo()

shared_ptr

基本概念

std::shared_ptr<T> 是共享所有权智能指针:

  • 多个 smart pointer 可指向同一对象;
  • 使用引用计数计管理资源生命周期;
  • 最后一个 shared_ptr 消失时才释放资源。

底层原理

数据结构

shared_ptr 中含有两个关键对象:

  1. 控制块(control block) 包含:
  • use_count(引用计数)
  • weak_count
  • 删除器 Deleter
  • 分配器 Allocator
  • 指向对象的指针
  1. shared_ptr 内部只有两个指针
cpp 复制代码
T* ptr;                // 指向对象
ControlBlock* ctrl;    // 指向控制块

创建方式

推荐:make_shared

cpp 复制代码
auto p = std::make_shared<int>(10);

优点:

  • 对象和控制块在同一块内存
  • 更少的内存分配
  • 更高的缓存局部性
  • 更安全(异常安全)

拷贝/赋值:引用计数 +1

cpp 复制代码
auto a = std::make_shared<int>(5);
auto b = a; // use_count = 2

离开作用域:引用计数 -1

引用计数变为 0 时执行删除器:

cpp 复制代码
~shared_ptr() {
    if (--ctrl->use_count == 0) {
        del(ptr);
    }
}

示例:shared_ptr 引用计数演示

cpp 复制代码
#include <iostream>
#include <memory>

int main() {
    std::shared_ptr<int> p1 = std::make_shared<int>(42);
    std::cout << p1.use_count() << "\n"; // 1

    {
        std::shared_ptr<int> p2 = p1;
        std::cout << p1.use_count() << "\n"; // 2
    }

    std::cout << p1.use_count() << "\n"; // 1
}

unique_ptr VS shared_ptr

特性 unique_ptr shared_ptr
所有权 独占 共享
拷贝 不可
移动
内存开销 小(仅一个指针) 大(含控制块)
生命周期 自动,但唯一 引用计数控制
性能 更快 较慢(原子操作)
适用场景 独占资源 多模块共享资源
相关推荐
不知所云,1 小时前
4. vscode c++ 环境及工程搭建 clangd + mingw
c++·ide·vscode·开发环境·clangd
kyle~1 小时前
数据结构---堆(Heap)
服务器·开发语言·数据结构·c++
apocelipes1 小时前
Linux的binfmt_misc机制
linux·c语言·c++·python·golang·linux编程·开发工具和环境
渡我白衣1 小时前
哈希的暴力美学——std::unordered_map 的底层风暴、扩容黑盒与哈希冲突终极博弈
java·c语言·c++·人工智能·深度学习·算法·哈希算法
qq_433554541 小时前
C++ 最大子段和(动态规划)
开发语言·c++·动态规划
lijiatu100861 小时前
[C++] lock_guard、unique_lock与条件变量wait()函数
开发语言·c++
2509_940880221 小时前
CC++链接数据库(MySQL)超级详细指南
c语言·数据库·c++
_F_y2 小时前
二分:山脉数组的峰顶索引、寻找峰值、寻找旋转排序数组中的最小值、点名
c++·算法
Elias不吃糖2 小时前
克隆图(LeetCode 133)——用数组做映射的 DFS 解法
c++·算法·leetcode·深度优先