- 浏览: 1478042 次
- 性别:
- 来自: 北京
文章分类
- 全部博客 (691)
- linux (207)
- shell (33)
- java (42)
- 其他 (22)
- javascript (33)
- cloud (16)
- python (33)
- c (48)
- sql (12)
- 工具 (6)
- 缓存 (16)
- ubuntu (7)
- perl (3)
- lua (2)
- 超级有用 (2)
- 服务器 (2)
- mac (22)
- nginx (34)
- php (2)
- 内核 (2)
- gdb (13)
- ICTCLAS (2)
- mac android (0)
- unix (1)
- android (1)
- vim (1)
- epoll (1)
- ios (21)
- mysql (3)
- systemtap (1)
- 算法 (2)
- 汇编 (2)
- arm (3)
- 我的数据结构 (8)
- websocket (12)
- hadoop (5)
- thrift (2)
- hbase (1)
- graphviz (1)
- redis (1)
- raspberry (2)
- qemu (31)
- opencv (4)
- socket (1)
- opengl (1)
- ibeacons (1)
- emacs (6)
- openstack (24)
- docker (1)
- webrtc (11)
- angularjs (2)
- neutron (23)
- jslinux (18)
- 网络 (13)
- tap (9)
- tensorflow (8)
- nlu (4)
- asm.js (5)
- sip (3)
- xl2tp (5)
- conda (1)
- emscripten (6)
- ffmpeg (10)
- srt (1)
- wasm (5)
- bert (3)
- kaldi (4)
- 知识图谱 (1)
最新评论
-
wahahachuang8:
我喜欢代码简洁易读,服务稳定的推送服务,前段时间研究了一下go ...
websocket的helloworld -
q114687576:
http://www.blue-zero.com/WebSoc ...
websocket的helloworld -
zhaoyanzimm:
感谢您的分享,给我提供了很大的帮助,在使用过程中发现了一个问题 ...
nginx的helloworld模块的helloworld -
haoningabc:
leebyte 写道太NB了,期待早日用上Killinux!么 ...
qemu+emacs+gdb调试内核 -
leebyte:
太NB了,期待早日用上Killinux!
qemu+emacs+gdb调试内核
C++11引入的三种智能指针中的最后一个:weak_ptr。在学习weak_ptr之前最好对shared_ptr有所了解。如果你还不知道shared_ptr是何物,可以看看我的另一篇文章【C++11新特性】 C++11智能指针之shared_ptr。
1、为什么需要weak_ptr?
在正式介绍weak_ptr之前,我们先来回忆一下shared_ptr的一些知识。我们知道shared_ptr是采用引用计数的智能指针,多个shared_ptr实例可以指向同一个动态对象,并维护了一个共享的引用计数器。对于引用计数法实现的计数,总是避免不了循环引用(或环形引用)的问题,shared_ptr也不例外。
我们先来看看下面这个例子:
上面代码的输出如下:
从上面代码中,ClassA和ClassB间存在着循环引用,从运行结果中我们可以看到:当main函数运行结束后,spa和spb管理的动态资源并没有得到释放,产生了内存泄露。
为了解决类似这样的问题,C++11引入了weak_ptr,来打破这种循环引用。
2、weak_ptr是什么?
weak_ptr是为了配合shared_ptr而引入的一种智能指针,它指向一个由shared_ptr管理的对象而不影响所指对象的生命周期,也就是将一个weak_ptr绑定到一个shared_ptr不会改变shared_ptr的引用计数。不论是否有weak_ptr指向,一旦最后一个指向对象的shared_ptr被销毁,对象就会被释放。从这个角度看,weak_ptr更像是shared_ptr的一个助手而不是智能指针。
3、weak_ptr如何使用?
接下来,我们来看看weak_ptr的简单用法。
3.1如何创建weak_ptr实例
当我们创建一个weak_ptr时,需要用一个shared_ptr实例来初始化weak_ptr,由于是弱共享,weak_ptr的创建并不会影响shared_ptr的引用计数值。
示例:
3.2如何判断weak_ptr指向对象是否存在
既然weak_ptr并不改变其所共享的shared_ptr实例的引用计数,那就可能存在weak_ptr指向的对象被释放掉这种情况。这时,我们就不能使用weak_ptr直接访问对象。那么我们如何判断weak_ptr指向对象是否存在呢?C++中提供了lock函数来实现该功能。如果对象存在,lock()函数返回一个指向共享对象的shared_ptr,否则返回一个空shared_ptr。
示例:
试试把sp.reset()这行的注释去掉看看结果有什么不同。
除此之外,weak_ptr还提供了expired()函数来判断所指对象是否已经被销毁。
示例:
代码输入如下:
A Constructor...
A Destructor...
3.3如何使用weak_ptr
weak_ptr并没有重载operator->和operator *操作符,因此不可直接通过weak_ptr使用对象,典型的用法是调用其lock函数来获得shared_ptr示例,进而访问原始对象。
最后,我们来看看如何使用weak_ptr来改造最前面的代码,打破循环引用问题。
输出结果如下:
从运行结果可以看到spa和spb指向的对象都得到释放!
————————————————
1、为什么需要weak_ptr?
在正式介绍weak_ptr之前,我们先来回忆一下shared_ptr的一些知识。我们知道shared_ptr是采用引用计数的智能指针,多个shared_ptr实例可以指向同一个动态对象,并维护了一个共享的引用计数器。对于引用计数法实现的计数,总是避免不了循环引用(或环形引用)的问题,shared_ptr也不例外。
我们先来看看下面这个例子:
#include <iostream> #include <memory> #include <vector> using namespace std; class ClassB; class ClassA { public: ClassA() { cout << "ClassA Constructor..." << endl; } ~ClassA() { cout << "ClassA Destructor..." << endl; } shared_ptr<ClassB> pb; // 在A中引用B }; class ClassB { public: ClassB() { cout << "ClassB Constructor..." << endl; } ~ClassB() { cout << "ClassB Destructor..." << endl; } shared_ptr<ClassA> pa; // 在B中引用A }; int main() { shared_ptr<ClassA> spa = make_shared<ClassA>(); shared_ptr<ClassB> spb = make_shared<ClassB>(); spa->pb = spb; spb->pa = spa; // 函数结束,思考一下:spa和spb会释放资源么? }
上面代码的输出如下:
ClassA Constructor... ClassB Constructor... Program ended with exit code: 0
从上面代码中,ClassA和ClassB间存在着循环引用,从运行结果中我们可以看到:当main函数运行结束后,spa和spb管理的动态资源并没有得到释放,产生了内存泄露。
为了解决类似这样的问题,C++11引入了weak_ptr,来打破这种循环引用。
2、weak_ptr是什么?
weak_ptr是为了配合shared_ptr而引入的一种智能指针,它指向一个由shared_ptr管理的对象而不影响所指对象的生命周期,也就是将一个weak_ptr绑定到一个shared_ptr不会改变shared_ptr的引用计数。不论是否有weak_ptr指向,一旦最后一个指向对象的shared_ptr被销毁,对象就会被释放。从这个角度看,weak_ptr更像是shared_ptr的一个助手而不是智能指针。
3、weak_ptr如何使用?
接下来,我们来看看weak_ptr的简单用法。
3.1如何创建weak_ptr实例
当我们创建一个weak_ptr时,需要用一个shared_ptr实例来初始化weak_ptr,由于是弱共享,weak_ptr的创建并不会影响shared_ptr的引用计数值。
示例:
int main() { shared_ptr<int> sp(new int(5)); cout << "创建前sp的引用计数:" << sp.use_count() << endl; // use_count = 1 weak_ptr<int> wp(sp); cout << "创建后sp的引用计数:" << sp.use_count() << endl; // use_count = 1 }
3.2如何判断weak_ptr指向对象是否存在
既然weak_ptr并不改变其所共享的shared_ptr实例的引用计数,那就可能存在weak_ptr指向的对象被释放掉这种情况。这时,我们就不能使用weak_ptr直接访问对象。那么我们如何判断weak_ptr指向对象是否存在呢?C++中提供了lock函数来实现该功能。如果对象存在,lock()函数返回一个指向共享对象的shared_ptr,否则返回一个空shared_ptr。
示例:
class A { public: A() : a(3) { cout << "A Constructor..." << endl; } ~A() { cout << "A Destructor..." << endl; } int a; }; int main() { shared_ptr<A> sp(new A()); weak_ptr<A> wp(sp); //sp.reset(); if (shared_ptr<A> pa = wp.lock()) { cout << pa->a << endl; } else { cout << "wp指向对象为空" << endl; } }
试试把sp.reset()这行的注释去掉看看结果有什么不同。
除此之外,weak_ptr还提供了expired()函数来判断所指对象是否已经被销毁。
示例:
class A { public: A() : a(3) { cout << "A Constructor..." << endl; } ~A() { cout << "A Destructor..." << endl; } int a; }; int main() { shared_ptr<A> sp(new A()); weak_ptr<A> wp(sp); sp.reset(); // 此时sp被销毁 cout << wp.expired() << endl; // true表示已被销毁,否则为false }
代码输入如下:
A Constructor...
A Destructor...
3.3如何使用weak_ptr
weak_ptr并没有重载operator->和operator *操作符,因此不可直接通过weak_ptr使用对象,典型的用法是调用其lock函数来获得shared_ptr示例,进而访问原始对象。
最后,我们来看看如何使用weak_ptr来改造最前面的代码,打破循环引用问题。
class ClassB; class ClassA { public: ClassA() { cout << "ClassA Constructor..." << endl; } ~ClassA() { cout << "ClassA Destructor..." << endl; } weak_ptr<ClassB> pb; // 在A中引用B }; class ClassB { public: ClassB() { cout << "ClassB Constructor..." << endl; } ~ClassB() { cout << "ClassB Destructor..." << endl; } weak_ptr<ClassA> pa; // 在B中引用A }; int main() { shared_ptr<ClassA> spa = make_shared<ClassA>(); shared_ptr<ClassB> spb = make_shared<ClassB>(); spa->pb = spb; spb->pa = spa; // 函数结束,思考一下:spa和spb会释放资源么? }
输出结果如下:
ClassA Constructor... ClassB Constructor... ClassA Destructor... ClassB Destructor... Program ended with exit code: 0
从运行结果可以看到spa和spb指向的对象都得到释放!
————————————————
发表评论
-
gcc链接顺序
2019-10-12 18:25 634代码在 https://github.com/killinux ... -
c++11的function和bind
2019-09-10 16:12 533参考:https://www.cnblogs.co ... -
opengl的helloworld
2014-10-22 19:41 9031.我提供一个不需要配置环境就可运行的源码。 glut.h放在 ... -
画图板用c++实现和用js实现的websocket版本
2014-10-17 13:02 2130画图板 opencv的c++ #include <o ... -
c语言内存
2014-07-02 10:26 6951、C中内存分为五个区 栈:用来存放函数的形参和函数内的局部变 ... -
重定向stdout到文件
2014-03-05 18:37 5485把stdout重定向到文件 两种方法: 第一种方法没有恢复 ... -
通过nginx远程执行shell
2014-03-03 10:26 5087saltstack远程执行shell,远程管理等返回json已 ... -
c的urldecode
2014-02-28 18:22 1363#include <stdio.h> #in ... -
pthread的pthread_mutex_lock 的使用
2014-02-25 16:54 26146参考http://haoningabc.iteye.com/b ... -
c调用c++
2013-10-12 15:24 1178参考 http://www.cppblog.com/frank ... -
用C语言,实现接收管道输出的结果,并显示
2013-04-23 21:35 1947在shell里利用“|”管道干的事情就是io重定向,把“|”命 ... -
关于char * 与 char[]
2013-04-22 21:56 962问题引入: 在实习过程中发现了一个以前一直默认的错误,同样ch ... -
单向链表翻转
2012-12-25 23:41 1021临时笔记,创建一个链表 #include <stdl ... -
trie 树 的代码
2012-12-14 23:20 1141想起搜狐老大的一句话 看代码先看h文件,擦,当初感觉他这句话很 ... -
指针函数与函数指针的区别
2012-12-14 22:44 1198一、 1、指针函数是指带指针的函数,即本质是一个函数。函数返回 ... -
指针和数组
2012-11-14 22:40 1069转载http://kan.weibo.com/con/3512 ... -
js备份
2012-10-31 23:56 1726<!DOCTYPE HTML PUBLIC " ... -
线程的helloworld
2012-10-30 21:51 1605#include<stdio.h> #inc ... -
c的书籍
2012-10-30 10:56 1130http://www.acm.uiuc.edu/webmonk ... -
深入理解计算机系统第三章笔记 gcc
2012-10-24 12:11 1531随便写个最简单程序 然后gcc -S 看汇编 在gcc -C ...
相关推荐
`shared_ptr`适合需要多个智能指针共享同一对象的情况,`unique_ptr`适用于独占所有权的资源管理,而`weak_ptr`则解决了循环引用的问题。了解并正确使用这些智能指针,是提升C++编程质量的关键。
其中,`weak_ptr`是为了解决`shared_ptr`中可能出现的循环引用问题而引入的一种特殊类型的智能指针。本文将深入探讨`weak_ptr`的概念、用途及其使用方法。 1. 为什么需要`weak_ptr`? `shared_ptr`是C++11中引入的...
`weak_ptr`主要用于解决`shared_ptr`可能导致的循环引用问题。例如,两个`shared_ptr`互相引用,如果它们之间没有其他强引用,就会形成一个无法自动释放的对象环。`weak_ptr`可以保持对对象的非拥有性引用,不会增加...
主要用于解决循环引用的问题,当对象被`shared_ptr`引用时,`weak_ptr`可以检测到对象是否仍然存在。 #### 特点: 1. **非拥有性**:`boost::weak_ptr` 不控制对象的生命周期,仅在对象存活时提供观察。 2. **避免...
5. 弱指针`std::weak_ptr`:与`std::shared_ptr`配合使用的弱指针不增加对象的引用计数,主要用于解决循环引用问题。当弱指针试图访问对象时,需要先检查对象是否仍然有效。 ```cpp std::weak_ptr<int> weak_ptr...
这在避免循环引用和处理依赖关系时非常有用。 总之,`shared_ptr`是C++中实现内存管理的重要工具,它提供了安全、方便的内存管理机制,使得开发者能更专注于业务逻辑,而不是内存管理。通过深入理解并熟练使用`...
为了解决这个问题,引入了`weak_ptr`。 ### weak_ptr `weak_ptr`被设计为对`shared_ptr`所指向的对象进行弱引用,它不增加引用计数,因此不会阻止所指向的对象被释放。`weak_ptr`的目的是提供一种访问已经被`...
`weak_ptr`通常用于解决`shared_ptr`的循环引用问题。在有循环引用的场景中,如果两个`shared_ptr`相互引用,它们的引用计数将永远不会降为零,导致内存无法释放。`weak_ptr`可以作为观察者,当`shared_ptr`引用计数...
解决循环引用的方法是使用`weak_ptr`。`weak_ptr`不会增加`shared_ptr`的引用计数,因此可以打破循环引用。修改上述代码,将`shared_ptr`替换为`weak_ptr`之一: ```cpp class B; // 前置声明 class A { public: ...
在C++编程中,合理地使用`shared_ptr`和`weak_ptr`能够有效地帮助开发者管理内存资源,特别是解决循环引用等复杂场景下的内存管理问题。理解这两种智能指针的特性以及如何正确使用它们,对于编写高质量、健壮的C++...
- **可与`std::weak_ptr`配合使用**:`std::weak_ptr`不增加引用计数,用于防止循环引用问题。 #### shared_ptr只能对new的内存操作 如标题所示,“shared_ptr只能对new的内存操作”这一说法强调了`std::shared_...
`weak_ptr`用于解决循环引用问题,当`shared_ptr`的引用计数为0时,即使有`weak_ptr`存在,对象也会被删除。在使用`weak_ptr`前,应先检查它是否有效,防止访问已被删除的对象。 4. `auto_ptr`:`auto_ptr`是C++98...
在实际编程中,程序员需要能够预见和识别可能产生循环引用的场景,并适时使用std::weak_ptr来解决这个问题。需要注意的是,std::weak_ptr是一种编译期的解决方案,并不能自动检测程序运行时产生的循环引用。因此,...
当`shared_ptr`不存在时,`weak_ptr`尝试访问对象会失败,这避免了引用循环和悬挂指针的问题。`weak_ptr`必须先转换为`shared_ptr`才能访问对象。 这些智能指针的设计旨在提高C++程序员的安全性和效率,减少内存...
`weak_ptr`主要用于打破循环引用,当两个`shared_ptr`相互引用时,它们的引用计数永远不会降为零,导致内存无法释放。通过使用`weak_ptr`,可以安全地跟踪一个对象,而不影响其生命周期。 智能指针的使用极大地提升...
weak_ptr 是一种弱智能指针,用于解决 shared_ptr 的循环引用问题。weak_ptr 不会增加引用计数,可以被用来观察对象的状态。 在使用智能指针时,需要注意以下几点: * 避免使用原始指针,避免内存泄漏和二次释放。...
`weak_ptr`通常用于打破循环引用,例如在上述描述中的HTTP类与时间节点类的互指问题。`weak_ptr`可以安全地观察`shared_ptr`管理的对象,而不会阻止对象的销毁。`use_count()`方法用于检查引用计数,`expired()`更...
### C++中的四种智能...`unique_ptr`适用于需要独占所有权的情况,`shared_ptr`适用于需要共享所有权的场合,而`weak_ptr`则用来解决循环引用问题。理解和熟练掌握这些智能指针的使用是每个C++开发者的基本技能之一。
这避免了循环引用的问题,当对象被所有std::shared_ptr释放后,std::weak_ptr尝试访问对象时会抛出异常。 智能指针的工作原理主要基于两个关键概念:资源获取即初始化(RAII, Resource Acquisition Is ...