c/c++ 智能指针 weak_ptr 使用
智能指针 weak_ptr 使用
weak_ptr用途:
1,解决空悬指针问题
2,解决循环引用问题
weak_ptr特点:没有*操作和->操作
weak_ptr是不控制所指对象生存周期的智能指针,它指向由一个shared_ptr管理的对象。将一个weak_ptr绑定到一个shared_ptr不会改变shared_ptr的计数器。一旦最后一个指向对象的shared_ptr被销毁,对象就会被释放,即使有weak_ptr指向这个对象,对象也会被释放。
一,先来个表格,唠唠weak_ptr
操作 | 功能描述 |
---|---|
weak_ptr<T> w | 空weak_ptr,可以指向类型为T*的对象。 |
weak_ptr<T> w(sp) | 与shared_sp sp指向相同对象的weak_ptr。T必须能转换为sp所指的类型。 |
w = p | p可以是一个shared_ptr或一个weak_ptr。赋值后w指向p所指的对象。 |
w.reset() | 将w置为空 |
w.use_count() | 与w共享对象的shared_ptr的数量 |
w.expired() | 若w.use_count()为0,返回true,否则返回false |
w.lock() | 如果expired()为true,返回一个空shared_ptr;否则返回一个指向w所指对象的shared_ptr。 |
小例子索引
代码块 | 功能描述 |
---|---|
test1 | weak_ptr不增加引用计数 |
test2 | weak_ptr没有->和*操作 |
test3 | lock使用 |
test4 | 循环引用,导致即使是智能指针也不能释放内存。用weak_ptr解决了循环引用,导致的内存不能释放的问题 |
小例子
#include <iostream>
#include <memory>
#include <vector>
using namespace std;
class Test{
public:
Test(int d = 0) : data(d){cout << "new" << data << endl;}
~Test(){cout << "del" << data << endl;}
void func(){cout << "func" << endl;}
private:
int data;
};
//test4 循环引用,导致即使是智能指针也不能释放内存
class teacher;
class student;
class teacher{
public:
teacher(){cout << "teacher()" << endl;}
~teacher(){cout << "del teacher" << endl;}
shared_ptr<student> stu;
};
class student{
public:
student(){cout << "student()" << endl;}
~student(){cout << "del student" << endl;}
//如果换成shared_ptr<teacher> tea;就会形成循环引用,导致内存泄漏
weak_ptr<teacher> tea;
};
int main(){
//test1 weak_ptr不增加引用计数
/*
shared_ptr<Test> sp1 = make_shared<Test>(1);
cout << sp1.use_count() << endl;//1
weak_ptr<Test> wp1 = sp1;
cout << wp1.use_count() << endl;//1
*/
//test2 weak_ptr没有->和*操作
//wp1->func();
//(*wp1).func();
//test3 lock使用
/*
shared_ptr<int> sptr;
sptr.reset(new int);
*sptr = 10;
weak_ptr<int> weak1 = sptr;
sptr.reset(new int);
*sptr = 5;
weak_ptr<int> weak2 = sptr;
// weak1 is expired!
if(auto tmp = weak1.lock())
cout << *tmp << '\n';
else
cout << "weak1 is expired\n";
// weak2 points to new data (5)
if(auto tmp = weak2.lock())
cout << *tmp << '\n';
else
cout << "weak2 is expired\n";
*/
//test4 循环引用,导致即使是智能指针也不能释放内存
//用weak_ptr解决了循环引用,导致的内存不能释放的问题
shared_ptr<teacher> tptr(new teacher);//计数器1
shared_ptr<student> sptr(new student);//计数器1
tptr->stu = sptr;//sptr的计数器2
sptr->tea = tptr;//不增加tptr的引用计数,因为tea是weak指针
cout << tptr.use_count() << endl;//1
cout << sptr.use_count() << endl;//2
return 0;
}
c/c++ 学习互助QQ群:877684253
本人微信:xiaoshitou5854
c/c++ 智能指针 weak_ptr 使用的更多相关文章
- 智能指针weak_ptr记录
智能指针weak_ptr为弱共享指针,实际上是share_ptr的辅助指针,不具备指针的功能.主要是为了协助 shared_ptr 工作,可用来观测资源的使用情况.weak_ptr 只对 shared ...
- C++智能指针--weak_ptr
weak_ptr是对对象的一种弱引用,它不会添加对象的引用计数.weak_ptr和shared_ptr之间能够相互转换.shared_ptr能够直接赋值给week_ptr,week_ptr可通过调用l ...
- Boost智能指针——weak_ptr
循环引用: 引用计数是一种便利的内存管理机制,但它有一个很大的缺点,那就是不能管理循环引用的对象.一个简单的例子如下: #include <string>#include <iost ...
- 智能指针weak_ptr解决循环依赖问题
#include <iostream> #include <memory> class Woman; class Man{ private: std::weak_ptr< ...
- [6] 智能指针boost::weak_ptr
[1]boost::weak_ptr简介 boost::weak_ptr属于boost库,定义在namespace boost中,包含头文件 #include<boost/weak_ptr.hp ...
- weak_ptr<T>智能指针
weak_ptr是为配合shared_ptr而引入的一种智能指针,它更像是shared_ptr的一个助手,而不是智能指针,因为它不具有普通指针的行为,没有重载operator*和operator-&g ...
- 智能指针shared_ptr新特性shared_from_this及weak_ptr
enable_shared_from_this是一个模板类,定义于头文件<memory>,其原型为: template< class T > class enable_shar ...
- 详解 boost 库智能指针(scoped_ptr<T> 、shared_ptr<T> 、weak_ptr<T> 源码分析)
一.boost 智能指针 智能指针是利用RAII(Resource Acquisition Is Initialization:资源获取即初始化)来管理资源.关于RAII的讨论可以参考前面的文章.在使 ...
- C++ | 再探智能指针(shared_ptr 与 weak_ptr)
上篇博客我们模拟实现了 auto_ptr 智能指针,可我们说 auto_ptr 是一种有缺陷的智能指针,并且在C++11中就已经被摈弃掉了.那么本章我们就来探索 boost库和C++11中的智能指针以 ...
随机推荐
- win32线程
win32线程 一丶什么是线程 在windows中常听到的就是线程.多线程.啊什么的. 这里介绍一下什么是线程. 1.线程是附属在进程中的一个执行实体.简而言之就是执行代码的. 2.每个进程至少有一个 ...
- perl选项、特殊变量、一些函数参考手册
perl一行式程序系列文章:Perl一行式 本文用来收集Perl一行式中涉及到的一些选项.特殊变量的说明,可以用来做速查手册. 本文会逐渐更新. 第一次学Perl一行式时,请直接忽略本文内容,并直接从 ...
- SpringBoot系列——快速构建项目
前言 springboot官方参考指南:https://docs.spring.io/spring-boot/docs/2.1.0.RELEASE/reference/htmlsingle/ Spri ...
- C#操作DbCommand类
一.常用属性 名称 说明 CommandText 获取或设置要对数据源执行的 Transact-SQL 语句.表名或存储过程 CommandTimeout 获取或设置在终止执行命令的尝试并生成错误之 ...
- [C#] C# 知识回顾 - Lambda
C# 知识回顾 - Lambda 序 它是第十一个希腊字母,一个拥有失意.无奈.孤独.低调等含义的流行符号,也指示一款称为“半条命”的游戏. 不过,这次我所讲的是 C# 中的 Lambda. 目录 L ...
- c# Cookie,Session,Application,Cache 四种缓存使用情景
好记性不如烂笔头,记录一下C#缓存使用的情景模式....个人理解,不正之处,欢迎指正 讨论 Cookie,Session,Application,Cache 四种,有的缓存情景对人,有的缓存情景对事儿 ...
- C# 给一个控件去掉焦点
给一个控件去掉焦点(如选中控件按钮button时,按钮出现方框显示):例如给form这个窗体中的button按钮去焦点1.首先在form这个窗体中拖一个label按钮,去文字,设置背景为透明: 2.然 ...
- 21.QT-QTreeWidget,QTabWidget
QTreeWidget树形列表 设置标签相关函数 void QTreeWidget::setHeaderItem (QTreeWidgetItem * item ); void QTreeWidget ...
- JVM运行时数据区内容简述
JVM运行时数据区分为五个部分:程序计数器.虚拟机栈.本地方法栈.堆.方法区.如下图所示,五部分其中又分为线程共享区域和线程私有区域,下面将分别介绍每一部分. 1. PC程序计数器 程序计数器是一块较 ...
- JavaScript机器学习之线性回归
译者按: AI时代,不会机器学习的JavaScript开发者不是好的前端工程师. 原文: Machine Learning with JavaScript : Part 1 译者: Fundebug ...