今天面试的时候被问到了一个问题,要我用模板类实现一个shared_ptr. 坦白来说这道题我并不会做,因为我对于shared_ptr的认知仅仅停留在引用计数上面。所以查阅了资料写了一份代码出来,希望对于更深入理解共享智能指针有帮助吧。

首先就是每个指针类应该有一个引用计数变量,以及一个模板指针,用于存放对应的不同类型的指针。对于shared_ptr来说,指针指向相同的位置,引用计数要加1. 同时,使用复制构造函数的时候,应该也会让引用变量加1,因为本身复制构造函数相同于使指针指向同一个地址。同时,应该重载=号,因为等于号也相当于让两个指针指向同一地址,在这里如果左操作符引用计数清零0就需要被析构,同时右操作符的引用计数需要加1.

综合上面的思路,写出来下面的代码:

#include <iostream>
#include <string>
#include <vector>
#include <queue>
#include <map>
#include <unordered_map>
#include <set>
#include <unordered_set>
using namespace std;template <typename T>
class Shared_ptr{
public:T *ptr;//实际指针int *p_count;//用于引用计数Shared_ptr(T *p){//第一次指向T类型的指针ptr = p;p_count = new int(1);//初始化,第一次指针指向的位置的引用计数应该是1}Shared_ptr(const Shared_ptr<T> & p){//复制构造函数this->ptr = p.ptr;this->p_count = p.p_count;//引用计数应该加1(*this->p_count)++;}Shared_ptr<T>  operator = (const Shared_ptr<T> & p){//重载等号if (ptr != p.ptr){//等号左边的引用计数减1,等号右边的引用计数加1*p_count--;if (*p_count == 0){delete p_count;delete ptr;}//指向=右边操作符,且计数变量+1ptr = p.ptr;p_count = p.p_count;*p_count++;}return *this;}T *operator->(){return ptr;}int use_count(){return *p_count;}
};
int main(){int *p = new int;*p = 5;Shared_ptr<int> s_ptr(p);//s_ptr指向了这块地址,pCount = 1cout << "s_ptr  count:" << s_ptr.use_count() << endl;cout << "--------------------------------------------------" << endl;Shared_ptr<int> s_ptr1 = s_ptr;//s_ptr1也指向了这块地址,pCount = 2cout << "s_ptr1:  count:" << s_ptr1.use_count() << endl;cout << "--------------------------------------------------" << endl;Shared_ptr<int> s_ptr2(p);//s_ptr2也指向了这块地址,不过重新创建了引用计数,pCount1 = 1cout << "s_ptr2:  count:" << s_ptr2.use_count() << endl;cout << "--------------------------------------------------" << endl;Shared_ptr<int> s_ptr3(s_ptr1);//s_ptr3指向s_ptr1,这样s_ptr,s_ptr1和s_ptr3都只向同一块内存空间,计数为3cout << "s_ptr3:  count:" << s_ptr3.use_count() << endl;//s_ptr4指向的和s_ptr3相同,那么两者的引用计数都应该加1cout << "--------------------------------------------------" << endl;Shared_ptr<int> s_ptr4 = s_ptr3;cout << "s_ptr3:  count:" << s_ptr3.use_count() << endl;cout << "s_ptr4:  count:" << s_ptr4.use_count() << endl;//system("pause");return 0;}

至于unique_ptr,因为从定义上,unique_ptr两个指针指向同一个地址,所以它的复制构造函数,和等号的重载都需要设置为不可用。参考实现如下:

#include <iostream>
#include <string>
#include <vector>
#include <queue>
#include <map>
#include <unordered_map>
#include <set>
#include <unordered_set>
using namespace std;template <typename T>
class unique_ptr{
public:T *ptr;unique_ptr(T *p){ptr = p;}~unique_ptr(){delete ptr;}T operator*(){return *ptr;}// =delete表示禁止使用编译器默认生成的函数,也就是该函数不可用unique_ptr(const unique_ptr<T> &p) = delete;unique_ptr<T> &operator=(const unique_ptr<T> & p) = delete;
};
int main(){int *p = new int(10);unique_ptr<int> u_ptr = p;cout << "u_ptr的值是: " << *u_ptr << endl;cout << "--------------------------------------------------" << endl;//unique_ptr<int> u_ptr2 = u_ptr;//报错,无法调用复制构造函数//unique_ptr<int> u_ptr3(u_ptr);//报错,无法调用复制构造函数system("pause");return 0;}

用模板类实现shared_ptr和unique_ptr相关推荐

  1. 智能指针shared_ptr、unique_ptr、weak_ptr

    智能指针 智能指针解决的问题 智能指针分类 shared_ptr 内存模型图 shared_ptr示例 shared_ptr含义 shared_ptr基本用法及常用函数 常用函数 智能指针的构造,初始 ...

  2. C++——智能指针——auto_ptr、shared_ptr、unique_ptr

    1.4.智能指针 智能指针是行为类似于指针的类对象. C++11 中提供了三种智能指针,使用这些智能指针时需要引用头文件 : ·shared_ptr; ·unique_ptr; ·auto_ptr; ...

  3. 《C++ Primer Plus》16.2 智能指针模板类

    智能指针是行为类似于指针的类对象,单这种对象还有其他功能.本节介绍三个可帮助管理动态内存分配的智能指针类.先来看看需要哪些功能以及这些功能是如何实现的.请看下面的函数: void remodel(st ...

  4. C++ 实现智能指针:shared_ptr 和 unique_ptr

    简 述: C++11 智能指针的深入分析,和动手实现简版的智能指针 std::shared_ptr .std::unique_ptr 文章目录 背景 std::shared_ptr 原理 代码 ref ...

  5. 一篇文章说清楚shared_ptr,unique_ptr的区别和关系

    一. shared_ptr的基本用法 (一)与unique_ptr的比较 比较 shared_ptr unique_ptr 备注 初始化 ①shared_ptr<T> sp; sp.res ...

  6. C++智能指针shared_ptr、unique_ptr以及weak_ptr

    目录 shared_ptr类 shared_ptr和unique_ptr都支持的操作 shared_ptr独有的操作 make_shared函数 shared_ptr自动销毁所管理的对象 由普通指针管 ...

  7. C++智能指针模板类

    对于常规类指针,可能由于忘记释放内存而导致内存泄漏,有三种智能指针可以解决这类问题. 对于常规指针,它没有析构函数,加入指针成为了对象,那么,在对象过期时就会自动调用析构函数,让析构函数释放指针指向的 ...

  8. 三维重建16:概率图模型 模板类编程

    刚刷了一部分网络题,又出了个模板类编程.没人能从面试中得到自己想要的方法,只能得到能看得到的结果!!! 一 概率图模型 贝叶斯模型,真是推导不出来了!贝叶斯函数貌似也写不出来了! 参考:斯坦福概率图模 ...

  9. 模板共享指针(shared_ptr)原理实现

    最近在书中看到关于智能指针的描述,由于之前没有使用过智能指针,便通过调试源代码(源代码的实现有点杂乱,并不能以最简单直观的方式呈现)了解原理后,以简单直接的方式写了一个shared_ptr指针类. 关 ...

最新文章

  1. STM32普通定时器(TIM2-7)的时钟源
  2. Tensorflow实战之下载MNIST数据,自动分成train, validation和test三个数据集
  3. timestamp 转换 mysql_技术分享 | MySQL:timestamp 时区转换导致 CPU %sys 高的问题
  4. 2020顶会指南:征稿截止时间、举办地、举办时间一览
  5. php 二维数组传递给 js 问题解决记录
  6. 【ubuntu】查看服务器上的进程占用GPU情况
  7. 2.2 流程控制-for序列 2.3 流程控制-for字典 2.4 循环退出 2.5 流程控制-while
  8. VB.net数据库编程pdf
  9. UBUNTU安装之后要配置的内容
  10. 钓鱼网站 (搬运自common craft )
  11. python程序设计课程设计二级减速器_二级减速器课程设计
  12. 联想电脑尺寸在哪里看_笔记本型号在哪里看 怎么看笔记本屏幕大小
  13. 发送ajax将浏览器卡死,jQuery Ajax同步参数致使浏览器假死怎么办
  14. Linux系统启动和内核管理
  15. 金融李素梅教授的《银行管理研究》课(1)
  16. 开关电源计算机仿真技术pdf,《开关电源仿真设计》PPT课件.ppt
  17. HTML实现简单的注册页面
  18. 不写一行代码就能开发?是真的,试试应用魔方吧
  19. Github中常见单词使用意思
  20. 深度剖析整数在内存中存储的问题

热门文章

  1. python自动化办公要学多久-深圳用python进行办公自动化都需要学习什么知识呢,谁来说下...
  2. python编程入门-Python 异步编程入门
  3. 零基础适合学python吗-零基础,经济学专业,适合自学Python吗?
  4. 科大讯飞输入法解锁高效语音输入
  5. start.bat怎么启动java项目_部署java项目为服务,设置开机自启动
  6. JavaScript创建页面节点
  7. SpringBoot 实现登录验证码(附集成SpringSecurity)
  8. 关于<meta name=“viewport“ content=“width=device-width,initial-scake=1.0, maximum-scale=1.0,user-s..“>
  9. golang mysql 工具类_golang操作mysql使用总结
  10. 滑动窗口:LeetCode 3 无重复字符的最长子串