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(10);

  • 移动所有权

    std::unique_ptr p1 = std::make_unique(5);
    std::unique_ptr 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
所有权 独占 共享
拷贝 不可
移动
内存开销 小(仅一个指针) 大(含控制块)
生命周期 自动,但唯一 引用计数控制
性能 更快 较慢(原子操作)
适用场景 独占资源 多模块共享资源
相关推荐
Qt程序员9 小时前
Linux RCU 原理与应用
linux·c++·内核·linux内核·rcu
qeen879 小时前
【C++】类与对象之类的默认成员函数(二)
android·c语言·开发语言·c++·笔记·学习
王老师青少年编程10 小时前
信奥赛C++提高组csp-s之搜索进阶(记忆化搜索案例实践3)
c++·记忆化搜索·方格取数·csp·信奥赛·csp-s·提高组
Titan202411 小时前
Linux动静态库
linux·服务器·c++
j_xxx404_12 小时前
MySQL表操作硬核解析:从 CREATE TABLE 到磁盘文件、ALTER TABLE 与 DDL 风险
运维·服务器·数据库·c++·mysql·adb·ai
wuminyu12 小时前
Java锁机制之park和unpark源码剖析
java·linux·c语言·jvm·c++
玖玥拾13 小时前
C/C++ 基础笔记(十一)类的进阶
c语言·c++·设计模式·
-森屿安年-13 小时前
1137. 第 N 个泰波那契数
c++·动态规划
程序员老舅14 小时前
从内核视角,看Linux文件读写过程
linux·服务器·c++·内核·linux内核·vfs·linux内存
Soari14 小时前
llama.cpp更新(b9553):LLM inference in C/C++,本地和云端实现高性能大模型推理
c语言·c++·llama