C++11(智能指针)

目录

一.智能指针的使用场景分析

二.RAII和智能指针的设计思路

三.C++标准库智能指针的使用

3.2. unique_ptr 的简单模拟

3.3shared_ptr 和 weak_ptr

3.4  shared_ptr循环引用问题

3.5 weak_ptr 


一.智能指针的使用场景分析


比如:我们new了以后,我们也delete了,但是因为抛异常导致后面的delete没有得到执行,所以就内存泄漏了,所以我们需要new以后捕获异常,捕获到异常后delete内存,再把异常抛出,但是因为new本身也可能抛异常,连续的new 和 自己抛的throw 都可能会抛异常,让我们处理起来很麻烦。智能指针放到这样的场景里面就让问题简单多了。

二.RAII和智能指针的设计思路


·RAll是Resource Acquisition Is Initialization的缩写,他是一种管理资源的类的设计思想,本质是
一种利用对象生命周期来管理获取到的动态资源,避免资源泄漏,这里的资源可以是内存、文件指
针、网络连接、互斥锁等等。RAII在获取资源时把资源委托给一个对象,接着控制对资源的访问,
资源在对象的生命周期内始终保持有效,最后在对象析构的时候释放资源,这样保障了资源的正常
释放,避免资源泄漏问题。

三.C++标准库智能指针的使用

C++标准库中的智能指针都在<memory>这个头文件下面

1. auto_ptr,强烈建议不要使用auto_ptr。因为他会使拷贝对象悬空,访问报错的问题,很多公司也是明令禁止使用这个智能指针的。

2. unique_ptr是C++11设计出来的智能指针,他的名字是唯一指针,他的特点的不支持拷
贝,只支持移动
。如果不需要拷贝的场景就非常建议使用他。

3.shared_ptr是C++11设计出来的智能指针,他的名字是共享指针,他的特点是支持拷贝,也支持移动。如果需要拷贝的场景就需要使用他了。底层是用引用计数的方式实现的。

4.weak_ptr是 C++11设计出来的智能指针,他的名字是弱指针他完全不同于上面的智能指针他不支持RAll,也就意味着不能用它直接管理资源,weak_ptr 的产生本质是要解决 shared_ptr的一个循环引用导致内存泄漏的问题。

3.2. unique_ptr 的简单模拟

3.3shared_ptr 和 weak_ptr

3.3.1 多个shared_ptr指向资源时就++引用计数,shared_ptr对象析构时就--引l用计数,引用计数减到o时代表当前析构的shared_ptr是最后一个管理资源的对象,则析构资源。

share_ptr 的 主要函数模拟:

3.4  shared_ptr循环引用问题


3.4.1 shared_ptr 大多数情况下管理资源非常合适,支持RAll,也支持拷贝。但是在循环引用的场景下会导致资源没得到释放内存泄漏,所以要学会使用weak_ptr解决这种问题。

下面就是循环引用例子:

 

 

1. n1和n2析构后,管理两个节点的引用计数减到1,右边的节点什么时候释放呢?左边节点中的_next管着呢,_next析构后,右边的节点就释放了。
2. _next什么时候析构呢,_next是左边节点的的成员,左边节点释放,_next就析构了。
3. 左边节点什么时候释放呢,左边节点由右边节点中的_prev管着呢,_prev析构后,左边的节点就释放了。
4. _prev什么时候析构呢,_prev是右边节点的成员,右边节点释放,_prev就析构了。
5. 至此逻辑上成功形成回旋镖似的循环引用,谁都不会释放就形成了循环引用,导致内存泄漏.


6. 把ListNode结构体中的_next和_prev改成weak_ptr,weak_ptr 绑定到 shared_ptr时不会增加它的引用计数,_next和_prev不参与资源释放管理逻辑,就成功打破了循环引用,解决了这里的问题.

比如:

3.5 weak_ptr 


weak_ptr不支持RAll,也不支持访问资源,所以我们看文档发现weak_ptr构造时不支持绑定到资
源,只支持绑定到shared_ptr,绑定到shared_ptr时,不增加shared_ptr的引用计数,那么就可以
解决上述的循环引用问题

### C++11智能指针的用法和特性 #### 使用场景与优势 C++11引入了三种主要类型的智能指针:`std::unique_ptr`, `std::shared_ptr` 和 `std::weak_ptr`。这些智能指针通过自动管理对象生命周期来提高程序安全性并减少内存泄漏的风险[^1]。 #### unique_ptr 的定义与使用方法 `std::unique_ptr` 是一种独占所有权的智能指针,意味着同一时间只有一个 `unique_ptr` 可以指向某个特定的对象实例。当 `unique_ptr` 被销毁时,它所拥有的资源也会被释放。 ```cpp #include <memory> // 创建一个指向整数的唯一指针 std::unique_ptr<int> p(new int(42)); ``` #### shared_ptr 的定义与使用方法 对于需要多个所有者共享同一个对象的情况,则可以使用 `std::shared_ptr`. 它内部实现了一个引用计数机制,每当有一个新的 `shared_ptr` 复制该指针时就会增加计数值;而当最后一个持有此指针的对象超出作用域或显式删除时才会真正释放关联的堆分配空间. ```cpp #include <memory> void foo(std::shared_ptr<int> sp){ *sp += 5; } int main(){ auto ptr = std::make_shared<int>(10); foo(ptr); // 不会触发深拷贝,因为只是传递给函数参数 } ``` #### weak_ptr 的定义与使用方法 为了避免循环引用问题,在某些情况下还需要配合 `std::weak_ptr` 来观察而不控制目标对象的生命期。这通常发生在两个对象相互保持对方存活的情况下(即A持有了B,B也持有了A),此时如果都采用强引用(`shared_ptr`)则会造成无法回收的问题. ```cpp class Node { public: ~Node() { /* ... */ } private: std::vector<std::weak_ptr<Node>> neighbors_; // 邻居节点列表只做观测用途 }; ``` 以上就是关于C++11智能指针的主要介绍以及它们各自的特性和应用场景.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值