C++ shared_ptr
发布日期:2021-05-07 15:11:18 浏览次数:18 分类:精选文章

本文共 2031 字,大约阅读时间需要 6 分钟。

shared_ptr智能指针详解

一、shared_ptr类概述

shared_ptr是C++中用于管理动态内存的智能指针,主要用于避免指针泄漏问题。它通过引用计数机制自动管理动态内存的生命周期。

1.1 使用shared_ptr的优势

  • 零错误风险:智能指针的引用计数机制确保不会出现悬而未决的指针。
  • 内存管理透明化:用户无需手动管理内存,减少内存泄漏风险。
  • 简化异常处理:即使在异常情况下,智能指针也能正确释放资源。

1.2 使用shared_ptr的基本规则

  • 内存只能由shared_ptr管理:不能将shared_ptr指针指向堆分配的内存。
  • 智能指针是唯一的拥有者:不要将其拷贝或赋值给其他智能指针或普通指针。
  • 避免使用过度共享:如果不再需要某个shared_ptr,及时释放它。

二、shared_ptr的创建与初始化

shared_ptr分为两种创建方式:显式初始化和隐式初始化。

2.1 显式初始化

shared_ptr
p1; // 空智能指针shared_ptr
p2 = make_shared
(42); // 指向42的智能指针shared_ptr
p3 = make_shared
(10, '9'); // 指向"9999"的智能指针

2.2 隐式初始化

shared_ptr
p4 = rvalue; // 可以接受任意类型的rvalueshared_ptr
p5 = {new int(1024)}; // 显式使用new创建

三、shared_ptr的核心功能

shared_ptr提供了一系列操作方法,确保内存管理的安全性。

3.1 引用计数机制

  • 每个shared_ptr对象都有一个引用计数器。
  • 拷贝或赋值操作会递增引用计数。
  • 当引用计数变为0时,shared_ptr会自动释放指针所指的内存。

3.2 拷贝与赋值

auto p = make_shared
(42);auto q = p; // q的引用计数变为2auto r = make_shared
(42);r = q; // r的引用计数变为2,q的引用计数变为1

3.3 内存释放规则

  • shared_ptr自动管理内存,只有最后一个持有者会释放内存。
  • 如果在使用shared_ptr时发生异常,内存仍会在异常处理完成后正确释放。

四、shared_ptr的异常处理

在异常情况下,shared_ptr能够确保资源的安全释放。

4.1 示例

void func() {    shared_ptr
sp(new int(42)); // 如果func中发生异常,sp会在栈 unwinding时自动释放内存}

4.2 比较使用new的风险

void func() {    int *ip = new int(42); // 不能在异常中确保释放内存    // 如果func中发生异常,ip可能指向释放后的内存或未释放的内存    delete ip; // 如果能执行到这里,会安全释放}

五、shared_ptr的删除器

shared_ptr支持定义删除器,用于定制内存释放逻辑。

5.1 示例

#include 
struct Handler { void operator()(connection *ptr) { delete ptr; }};shared_ptr
p = make_shared
(new connection);p.reset(&connection::destroy); // 自定义删除器

六、shared_ptr的实际应用场景

6.1 动态数组管理

vector
> v;v.push_back(make_shared
(1024));v.resize(10); // 创建10个shared_ptr

6.2 资源管理

class Resource {public:    ~Resource() { // 自动释放资源        // cleanup logic    }};shared_ptr
ptr = make_shared
();

7、总结

shared_ptr通过智能引用计数机制和自动删除器,简化了动态内存管理的复杂性。它的主要优点是内存管理透明化、错误风险降低以及内存泄漏的可能性大大减少。

上一篇:C++ weak_ptr
下一篇:C++ throw、try、catch、noexcept

发表评论

最新留言

网站不错 人气很旺了 加油
[***.192.178.218]2025年04月02日 19时39分23秒