STL源码剖析-waked_ptr
目录
一、提问
二、 代码实现
2.1 mweak_ptr的具体实现
2.2 测试用例
一、提问
weak_ptr为什么会存在?shared_ptr不是已经有了引用计数吗?具体原因详见模拟实现boost库中的shared_ptr,简单来说就是为了解决循环引用(交叉引用)的问题。
weak_ptr是为了配合shared_ptr而引入的一种智能指针,更像是shared_ptr的一个助手而不是智能指针(不具备普通指针的行为operator*和operator->),最大的作用在于协助shared_ptr工作,像旁观者那样观测资源的使用情况!weak_ptr是与shared_ptr协同工作的:获取资源的观测权,并没有共享资源!而构造weak_ptr不会引起引用计数的变化。
二、 代码实现
2.1 mweak_ptr的具体实现
为了和boost库中的weak_ptr区分,我在命名时加上了m(含义是my)。mshared_ptr已在文首的模拟实现boost库中的shared_ptr讨论过了,故而不在赘述。先将代码粘贴如下。
mshared_ptr部分:
#include<iostream>
using namespace std;
#include<map>
template<typename T>
class mweak_ptr;
template<typename T>
class mshared_ptr
{
public:
mshared_ptr(T *ptr = NULL); //构造方法
~mshared_ptr(); //析构方法
mshared_ptr(mshared_ptr<T> &src); //拷贝构造
mshared_ptr& operator = (mshared_ptr<T> &src); //赋值运算符重载
T& operator*(); //解引用运算符重载
T* operator->(); //成员运算符重载
private:
T *_ptr;
static map<T*, int> _map; //静态数据成员需要在类外进行初始化
friend class mweak_ptr<T>;
};
template<typename T>
map<T*, int> mshared_ptr<T>::_map;
template<typename T>
mshared_ptr<T>::mshared_ptr(T *ptr) //构造方法
{
cout << "mshared_ptr的构造方法正被调用!" << endl;
_ptr = ptr;
_map.insert(make_pair(_ptr, 1));
}
template<typename T>
mshared_ptr<T>::~mshared_ptr() //析构方法
{
cout << "mshared_ptr的析构方法正被调用!" << endl;
if (--_map[_ptr] <= 0 && NULL != _ptr)
{
delete _ptr;
_ptr = NULL;
_map.erase(_ptr);
}
}
template<typename T>
mshared_ptr<T>::mshared_ptr(mshared_ptr<T> &src) //拷贝构造
{
cout << "mshared_ptr的拷贝构造方法正被调用!" << endl;
_ptr = src._ptr;
_map[_ptr]++;
}
template<typename T>
mshared_ptr<T>& mshared_ptr<T>::operator=(mshared_ptr<T> &src) //赋值运算符重载
{
if (_ptr == src._ptr)
{
return *this;
}
if (--_map[_ptr] <= 0 && NULL != _ptr)
{
delete _ptr;
_ptr = NULL;
_map.erase(_ptr);
}
_ptr = src._ptr;
_map[_ptr]++;
return *this;
}
template<typename T>
T& mshared_ptr<T>::operator*() //解引用运算符重载
{
return *_ptr;
}
template<typename T>
T* mshared_ptr<T>::operator->() //成员运算符重载
{
return _ptr;
}
mweak_ptr部分
template<typename T>
class mweak_ptr
{
public:
mweak_ptr(){} //需要提供一个默认的构造方法
mweak_ptr(mshared_ptr<T> &src); //构造方法
mshared_ptr<T> lock();
private:
mshared_ptr<T> *_ptr;
};
template<typename T>
mweak_ptr<T>::mweak_ptr(mshared_ptr<T> &src) //使用强指针进行构造
{
_ptr = &src;
}
template<typename T>
mshared_ptr<T> mweak_ptr<T>::lock() //返回一个可用的强指针
{
int count = _ptr->_map[_ptr->_ptr];
if (count > 0) //从shared_ptr获得一个可用的shared_ptr对象。从而操作资源
{
return *_ptr;
}
else
{
return NULL;
}
}
void test(mweak_ptr<int> mweak_p)
{
cout << *mweak_p.lock() << endl;
}
2.2 测试用例
class B;
class A
{
public:
mweak_ptr<B>_ptr_B; //类内存放的是弱指针,将在合适的时间转变成强指针!
};
class B
{
public:
mweak_ptr<A>_ptr_A;
};
int main()
{
mshared_ptr<A>ptr_A(new A);
mshared_ptr<B>ptr_B(new B);
ptr_A->_ptr_B = ptr_B;
ptr_B->_ptr_A = ptr_A;
return 0;
}
图1 VS2017下验证结果
从图中可以看到,构造方法和析构方法的执行次数是相同的,故而引用计数没有被占用,申请的内存成功被释放了。
————————————————
版权声明:本文为CSDN博主「楚楚可薇」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_41822235/article/details/82936615
STL源码剖析-waked_ptr的更多相关文章
- STL"源码"剖析-重点知识总结
STL是C++重要的组件之一,大学时看过<STL源码剖析>这本书,这几天复习了一下,总结出以下LZ认为比较重要的知识点,内容有点略多 :) 1.STL概述 STL提供六大组件,彼此可以组合 ...
- 【转载】STL"源码"剖析-重点知识总结
原文:STL"源码"剖析-重点知识总结 STL是C++重要的组件之一,大学时看过<STL源码剖析>这本书,这几天复习了一下,总结出以下LZ认为比较重要的知识点,内容有点 ...
- (原创滴~)STL源码剖析读书总结1——GP和内存管理
读完侯捷先生的<STL源码剖析>,感觉真如他本人所说的"庖丁解牛,恢恢乎游刃有余",STL底层的实现一览无余,给人一种自己的C++水平又提升了一个level的幻觉,呵呵 ...
- 《STL源码剖析》环境配置
首先,去侯捷网站下载相关文档:http://jjhou.boolan.com/jjwbooks-tass.htm. 这本书采用的是Cygnus C++ 2.91 for windows.下载地址:ht ...
- STL源码剖析读书笔记之vector
STL源码剖析读书笔记之vector 1.vector概述 vector是一种序列式容器,我的理解是vector就像数组.但是数组有一个很大的问题就是当我们分配 一个一定大小的数组的时候,起初也许我们 ...
- STL源码剖析 迭代器(iterator)概念与编程技法(三)
1 STL迭代器原理 1.1 迭代器(iterator)是一中检查容器内元素并遍历元素的数据类型,STL设计的精髓在于,把容器(Containers)和算法(Algorithms)分开,而迭代器(i ...
- STL"源码"剖析
STL"源码"剖析-重点知识总结 STL是C++重要的组件之一,大学时看过<STL源码剖析>这本书,这几天复习了一下,总结出以下LZ认为比较重要的知识点,内容有点略 ...
- 《STL源码剖析》相关面试题总结
原文链接:http://www.cnblogs.com/raichen/p/5817158.html 一.STL简介 STL提供六大组件,彼此可以组合套用: 容器容器就是各种数据结构,我就不多说,看看 ...
- STL源码剖析之序列式容器
最近由于找工作需要,准备深入学习一下STL源码,我看的是侯捷所著的<STL源码剖析>.之所以看这本书主要是由于我过去曾经接触过一些台湾人,我一直觉得台湾人非常不错(这里不涉及任何政治,仅限 ...
随机推荐
- redis的RDB和AOF两种持久化机制
思维导图:我的redis基础知识汇总 RDB持久化机制的优点 (1)RDB会生成多个数据文件,每个数据文件都代表了某一个时刻中redis的数据,这种多个数据文件的方式,非常适合做冷备,可以将这种完整的 ...
- 洛谷 P5224 - Candies(循环卷积)
洛谷题面传送门 一道题解长度大概不到 1k 的题,可还是决定写篇题解,因为自己没有做出来( \(1004535809\) 好评( 首先这个 \(\equiv m\pmod{k}\) 有点把我们往单位根 ...
- 【R】如何将重复行转化为多列(一对一转化一对多)?
目录 需求 方法一 方法二 需求 一个数据框一列或多列中有重复行,如何将它的重复行转化为多列?即本来两列一对一的关系,如何转化为一对多的关系?普通的spread函数实现较为麻烦. 示例数据如下: It ...
- Nginx编译安装相关参数
Nginx编译安装相关参数 Nginx插件安装 ------------------pcre------------------ cd /usr/local/source wget http://ww ...
- R语言与医学统计图形-【27】ggplot2图形组合、字体、保存
ggplot2绘图系统--图形组合.字体选择.保存输出 1.图形组合 一页多图在基础包中利用par和layout函数来切分画布. ggplot2是先铺好网格背景,再进行绘图,所以要通过切分网格背景来实 ...
- CPU大小端模式及转换
通信协议中的数据传输.数组的存储方式.数据的强制转换等这些都会牵涉到大小端问题. CPU的大端和小端模式很多地方都会用到,但还是有许多朋友不知道,今天暂且普及一下. 一.为什么会有大小端模式之分呢? ...
- lua5.4 beta中的to-be-closed变量的用法
对应目前最新lua5.4 beta版本:2019-10-09发布 这个功能之前修改过两次语法,当前的语法不出意外将会是最终决定了,目前还没有最新的中文资料,所以我来这里发一下. 先介绍下这个功能: 被 ...
- 05 Windows安装python3.6.4+pycharm环境
windows安装python3.6.4环境 使用微信扫码关注微信公众号,并回复:"Python工具包",免费获取下载链接! 一.卸载python环境 卸载以下软件: 二.安装py ...
- 巩固java第七天
巩固内容: HTML 属性 属性是 HTML 元素提供的附加信息. HTML 属性 HTML 元素可以设置属性 属性可以在元素中添加附加信息 属性一般描述于开始标签 属性总是以名称/值对的形式出现,比 ...
- aboard, abolish
aboard board做动词有上车/船/飞机的意思,boarding就是正在上.board做名词有板的意思,车厢地板的板. a是个词根,有三种意思:1. 以某种状态或方式,如: ablaze, af ...