C++11 智能指针概述

0.什么是智能指针?

智能指针是一种用来管理资源指针的特殊对象,对象中有一个成员变量用来保存动态创建的裸指针,通过重载operator->方法实现类似于裸指针的使用方式。

1.智能指针的作用是什么?

我们平时使用C++编写代码时,动态内存管理是我们时刻关注的重点。动态内存管理不好,容易出现下述三类问题:

1、野指针(空悬指针)

一些内存单元已经被释放,但是指向这些内存的指针还在使用,这些已经释放的内存有可能被系统重新分配给应用使用,此时再使用野指针,会造成无法预测的错误。

int *p = new int(10);
delete p;

//  释放后再次访问,无法预测结果
cout << *p << endl;

2、重复释放

程序试图释放已经被释放的资源,或者已经被重新分配的资源。

int *p = new int(10);

delete p;

//  重复释放,运行时报错
delete p;

3、内存泄露

不再使用的动态内存没有进行释放,便会造成内存泄露。如果程序多次存在内存泄露行为,会导致内存占用急剧增长,最终程序会因为无法申请到足够的空闲内存而异常退出。

void TestRelease()
{
	int* p = new int(10);
    
    //  未释放p
	return;
}

这三类问题严重影响程序的高可用性。但是像JAVA这样的语言不会存在这样的问题,因为它们拥有比较好的内存回收机制,可以自动管理动态内存。为了保证资源可以正常释放,C++引入智能指针。智能指针的行为类似常规指针,重要的区别是它负责自动释放所指向的对象。

智能指针的主要思想是RAII思想,即”资源获取即初始化“:

(1)定义一个类来封装资源的分配和释放

(2)构造函数中完成资源的分配及初始化

(3)析构函数中完成资源的清理,可以保证资源的正确初始化和释放

(4)如果对象是在栈上创建的,那么RAII机制就会正常工作,当离开作用域对象会自动销毁,从而自动调用洗过后函数释放资源

2.C++11标准库中的智能指针

C++11中提供了三种智能指针来动态管理创建的对象。

1、std::shared_ptr<T>基于引用计数的智能指针,允许多个对象指向同一个资源;

2、std::unique_ptr<T>独占式智能指针,任何时刻一个资源只能由一个对象占用;

3、std::weak_ptr<T>是一种不控制所指向对象生存期的智能指针,它指向一个由shared_ptr管理的对象,将一个weak_ptr绑定到一个shared_ptr不会改变shared_ptr的引用计数。

 

### C++11 智能指针概述 C++11引入了三种主要的智能指针类型:`std::shared_ptr`, `std::unique_ptr` 和 `std::weak_ptr`,这些智能指针提供了自动管理动态分配对象的功能,从而减少了内存泄漏的风险[^1]。 #### 头文件包含 为了使用上述任何一种智能指针,程序需要包含 `<memory>` 头文件: ```cpp #include <memory> ``` #### Smart Pointers 的区别 - **`std::shared_ptr<T>`**: 支持多个指针指向同一个对象。内部维护一个引用计数器来跟踪有多少个共享指针持有该资源;当最后一个共享指针被销毁或重置时,所持有的资源会被释放。 - **`std::unique_ptr<T>`**: 提供独占所有权语义,即同一时间只有一个 `unique_ptr` 可以拥有某个特定的对象实例。不允许复制操作,但是支持移动语义。 - **`std::weak_ptr<T>`**: 不增加引用计数,通常作为观察者存在,用于解决循环引用问题。它必须通过锁定机制转换成 `shared_ptr` 才能访问实际的数据。 #### 初始化示例 ##### Shared Pointer 示例 可以利用 make_shared 函数简化创建过程并提高性能: ```cpp auto sp = std::make_shared<int>(42); // 创建一个新的 int 类型的 shared_ptr 并赋初值为 42 ``` 也可以直接指定已有的原始指针给 shared_ptr : ```cpp int* rawPtr = new int(7); std::shared_ptr<int> sp(rawPtr); delete rawPtr; // 错误做法, 应由 smart pointer 自动处理 // 正确的方式是由 smart pointer 负责 delete ``` ##### Unique Pointer 示例 对于唯一所有权的情况,则推荐使用 unique_ptr ,其构造方式如下所示: ```cpp std::unique_ptr<std::vector<BYTE>> data(std::make_unique<std::vector<BYTE>>()); // 或者更简洁的形式 auto uptr = std::make_unique<std::vector<BYTE>>(); ``` 这里采用了 `std::make_unique()` 来代替显式的 `new` 表达式,这不仅更加安全而且提高了可读性和效率[^2]。 ##### Weak Pointer 示例 弱指针本身并不控制对象生命周期,因此不能直接解引用获取数据成员,而是要先调用 lock() 方法获得临时的强引用版本: ```cpp std::shared_ptr<int> p(new int(42)); std::weak_ptr<int> wp(p); if (auto lockedWP = wp.lock()) { *lockedWP += 1; } else { // 对象已经被析构掉了... } ``` #### 使用注意事项 - 尽量避免不必要的拷贝动作,尤其是针对 `shared_ptr` ,因为每次拷贝都会引起额外开销; - 如果确实需要用到多线程环境下的共享资源,请考虑同步措施防止竞态条件发生; - 当只需要单次使用的场景下优先选用 `unique_ptr` ; - 循环依赖可能导致无法正常回收内存的问题,此时应采用 `weak_ptr` 断开链条中的某些环节.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值