智能指针 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. java ReentrantLock

    介绍 ReentrantLock称为重入锁,比内部锁synchonized拥有更强大的功能,它可中断.可定时.设置公平锁 [注]使用ReentrantLock时,一定要释放锁,一般释放放到finnal ...

  2. solr调用lucene底层实现倒排索引源码解析

    1.什么是Lucene? 作为一个开放源代码项目,Lucene从问世之后,引发了开放源代码社群的巨大反响,程序员们不仅使用它构建具体的全文检索应用,而且将之集成到各种系统软件中去,以及构建Web应用, ...

  3. 翻译:CREATE TRIGGER语句(已提交到MariaDB官方手册)

    本文为mariadb官方手册:CREATE TRIGGER的译文. 原文:https://mariadb.com/kb/en/create-trigger/我提交到MariaDB官方手册的译文:htt ...

  4. SpringBoot之打成war包部署到Tomcat

    正常情况下SpringBoot项目是以jar包的形式,正常情况下SpringBoot项目是以jar包的形式,并且SpringBoot是内嵌Tomcat服务器,所以每次重新启动都是用的新的Tomcat服 ...

  5. SpringBoot系列——WebSocket

    关于websocket的介绍与实现,我之前写过一篇博客,记录了用springboot-websocket实现了私聊.群聊的简单实例,这里就只提供一个入口,不再重复的写了,WebSocket+Java ...

  6. 南大算法设计与分析课程复习笔记(4)L4 - QuickSort

    一.快速排序 算法导论上关于快速排序有两种写法 第一种,从头到尾遍历,不断将小于基准元素的项移到前面.代码很简介,只需要维护一个交换位置,表示小于基准元素的末尾位置加一 我们看算法导论上的一个例子: ...

  7. golang高性能RPC:Apache Thrift安装使用完全攻略

    在企业应用中RPC的使用可以说是十分的广泛,使用该技术可以方便的与各种程序交互而不用考虑其编写使用的语言. 如果你对RPC的概念还不太清楚,可以点击这里. 现今市面上已经有许多应用广泛的RPC框架,比 ...

  8. C# 显式转换关键字 explicit

    不同于隐式转换,显式转换运算符必须通过转换的方式来调用. 如果转换操作会导致异常或丢失信息,则应将其标记为 explicit. 这可阻止编译器静默调用可能产生意外后果的转换操作. 省略转换将导致编译时 ...

  9. [转]docker基础详解

    本文转自:https://blog.csdn.net/xsj_blog/article/details/71700032 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog ...

  10. T-SQL :SQL Server系统数据库(二)

    master:master数据库储存实例范围的元数据信息,服务器配置,实例中的所有数据库信息和初始化信息. Resource:Resource数据库是一个隐藏,只读数据库,存储所有系统对象的定义.当查 ...