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中的智能指针以 ...
随机推荐
- 痞子衡嵌入式:蓝牙芯片厂商三强(Qualcomm&CSR, TI, Nordic)产品一览
大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是蓝牙芯片三强厂商的芯片. IoT物联网是未来的趋势,半导体厂商作为IoT产业的上游,主要提供核心的无线芯片,蓝牙是比较主流的协议,下面痞 ...
- 不能在此路径中使用此配置节。如果在父级别上锁定了该节,便会出现这种情况。锁定是默认设置的(overrideModeDefault="Deny"),或者 是通过包含 overrideMode="Deny" 或旧有的 allowOverride="false" 的位置标记明确设置的。
问题: 不能在此路径中使用此配置节.如果在父级别上锁定了该节,便会出现这种情况.锁定是默认设置的(overrideModeDefault="Deny"),或者是通过包含 overr ...
- C#泛型。
作用: 使用泛型可以实现算法重用. class Program { static void Main(string[] args) { MyClass<string> myClass = ...
- ABP适配Oracle全过程
一.背景 ABP的各类文档在网络上已经非常完善了,唯独缺少与oralce相关的资料,ABP官网也未给出一个较好的Oracle解决方案.正好最近在学习ABP相关知识,对ABP源码结构稍算熟悉,花了些 ...
- .Net 登陆的时候添加验证码
一.ASPX 登陆界面验证码 1.登陆验证码图片和输入验证码框 <asp:TextBox ID="txtValiCode" runat="server" ...
- Docker镜像目录无法删除
docker pull下来的镜像目录默认放在:C:\ProgramData\docker\windowsfilter.由于拉下来的镜像已经几乎占满了C盘的空间,准备删除所有的镜像,却发现删除不掉. 搜 ...
- python_字符串的操作
一:字符串的方法与操作 *注意:首字母为l的为从左边操作,为r的方法为从右边操作 1.__contains__()判断是否包含 判断指定字符或字符串是否包含在一个字符串内,返回值为true或者fals ...
- 【Java每日一题】20170309
20170308问题解析请点击今日问题下方的“[Java每日一题]20170309”查看(问题解析在公众号首发,公众号ID:weknow619) package Mar2017; public cla ...
- 【Java每日一题】20170227
20170224问题解析请点击今日问题下方的“[Java每日一题]20170227”查看(问题解析在公众号首发,公众号ID:weknow619) package Feb2017; import jav ...
- MyBatis:GeneratorConfig生成mapper以及pojo
首先我们需要导入相应的依赖 之后需要针对的配置一些数据 接着我们需要针对性的写配置文件,在根目录下写mybatis的主要配置文件 如上图我们配置了数据库连接.对应的一些pojo.mapper.java ...