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
所有权 独占 共享
拷贝 不可
移动
内存开销 小(仅一个指针) 大(含控制块)
生命周期 自动,但唯一 引用计数控制
性能 更快 较慢(原子操作)
适用场景 独占资源 多模块共享资源
相关推荐
炸膛坦客4 小时前
单片机/C/C++八股:(二十六)IIC 专题(I²C)---- 上集
c语言·c++·单片机
旖-旎4 小时前
LeetCode 518:零钱兑换||(完全背包)—— 题解
c++·算法·leetcode·动态规划·背包问题
Henry Zhu1235 小时前
C++中的特殊成员函数与智能指针
c++
_wyt0017 小时前
多重背包问题详解
c++·背包dp
Ljwuhe8 小时前
C++——多态
开发语言·c++
越甲八千8 小时前
STL stack为何没有迭代器
c++
从零开始的代码生活_10 小时前
C++ 继承详解:访问控制、对象模型、菱形继承与设计取舍
开发语言·c++·后端·学习·算法
云小逸10 小时前
【C++ 第七阶段:模板、泛型编程与工程综合详解】
开发语言·c++
GIS阵地11 小时前
QgsSingleBandPseudoColorRenderer 完整详解(QGIS 3.40.13 C++)
开发语言·前端·c++·qt·qgis
王维同学11 小时前
[原创][Windows C++]LSA 认证、安全与通知包的注册表枚举
c++·windows·安全