智能指针 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;
}

github完整代码

c/c++ 学习互助QQ群:877684253

本人微信:xiaoshitou5854

c/c++ 智能指针 weak_ptr 使用的更多相关文章

  1. 智能指针weak_ptr记录

    智能指针weak_ptr为弱共享指针,实际上是share_ptr的辅助指针,不具备指针的功能.主要是为了协助 shared_ptr 工作,可用来观测资源的使用情况.weak_ptr 只对 shared ...

  2. C++智能指针--weak_ptr

    weak_ptr是对对象的一种弱引用,它不会添加对象的引用计数.weak_ptr和shared_ptr之间能够相互转换.shared_ptr能够直接赋值给week_ptr,week_ptr可通过调用l ...

  3. Boost智能指针——weak_ptr

    循环引用: 引用计数是一种便利的内存管理机制,但它有一个很大的缺点,那就是不能管理循环引用的对象.一个简单的例子如下: #include <string>#include <iost ...

  4. 智能指针weak_ptr解决循环依赖问题

    #include <iostream> #include <memory> class Woman; class Man{ private: std::weak_ptr< ...

  5. [6] 智能指针boost::weak_ptr

    [1]boost::weak_ptr简介 boost::weak_ptr属于boost库,定义在namespace boost中,包含头文件 #include<boost/weak_ptr.hp ...

  6. weak_ptr<T>智能指针

    weak_ptr是为配合shared_ptr而引入的一种智能指针,它更像是shared_ptr的一个助手,而不是智能指针,因为它不具有普通指针的行为,没有重载operator*和operator-&g ...

  7. 智能指针shared_ptr新特性shared_from_this及weak_ptr

    enable_shared_from_this是一个模板类,定义于头文件<memory>,其原型为: template< class T > class enable_shar ...

  8. 详解 boost 库智能指针(scoped_ptr<T> 、shared_ptr<T> 、weak_ptr<T> 源码分析)

    一.boost 智能指针 智能指针是利用RAII(Resource Acquisition Is Initialization:资源获取即初始化)来管理资源.关于RAII的讨论可以参考前面的文章.在使 ...

  9. C++ | 再探智能指针(shared_ptr 与 weak_ptr)

    上篇博客我们模拟实现了 auto_ptr 智能指针,可我们说 auto_ptr 是一种有缺陷的智能指针,并且在C++11中就已经被摈弃掉了.那么本章我们就来探索 boost库和C++11中的智能指针以 ...

随机推荐

  1. python 闯关之路二(模块的应用)

    1.有如下字符串:n = "路飞学城"(编程题) - 将字符串转换成utf-8的字符编码的字节,再将转换的字节重新转换为utf-8的字符编码的字符串 - 将字符串转换成gbk的字符 ...

  2. python 闯关之路四(上)(并发编程与数据库理论)

    并发编程重点: 并发编程:线程.进程.队列.IO多路模型 操作系统工作原理介绍.线程.进程演化史.特点.区别.互斥锁.信号. 事件.join.GIL.进程间通信.管道.队列. 生产者消息者模型.异步模 ...

  3. 【Git】时光机命令—Git命令

    cd c:    进入C盘 mkdir learngit          创建名为learngit的文件夹 cd learngit  进入learngit文件夹 pwd    显示当前目录路径 gi ...

  4. Go基础系列:互斥锁Mutex和读写锁RWMutex用法详述

    sync.Mutex Go中使用sync.Mutex类型实现mutex(排他锁.互斥锁).在源代码的sync/mutex.go文件中,有如下定义: // A Mutex is a mutual exc ...

  5. AFNetworking封装-项目使用

    本篇博客是接着上一篇AFNetworking源码解析的后续,如果想对AFNetworking源码有所了解. 请读一下https://www.cnblogs.com/guohai-stronger/p/ ...

  6. [转]Docker和Rancher的安装与基本使用

    本文转自:https://blog.csdn.net/wangshouhan/article/details/80405672 一.Docker1.CentOS下Docker安装 安装 $ yum - ...

  7. C#正则表达式。

    什么是正则表达式: 正则表达式是用来进行文本处理的技术,是语言无关的. 是由普通字符和特殊字符组成的文字模式,用来描述字符串的特征. 元字符: 1.  .    :  除 \n 以外的任意的单个字符. ...

  8. 在 UWP 中实现 Expander 控件

    WPF 中的 Expander 控件在 Windows 10 SDK 中并不提供,本文主要说明,如何在 UWP 中创建这样一个控件.其效果如下图: 首先,分析该控件需要的一些特性,它应该至少包括如下三 ...

  9. spring_01概念及案例

    1.什么是IOC? IOC概念:inverse of Controll,控制反转,所谓控制反转,就是把创建对象和维护对象关系的权利从程序中转移到spring的容器中(applicationContex ...

  10. JSJ——java基本概念一

    Java曾以什么优点吸引你走上程序员这条不归路? 友好的语法.面向对象.内存管理和最棒的跨平台可移植性.write-once/run-anywhere 当然,只有我们真正投身入java才发现有bug要 ...