C++面试题(四)——智能指针的原理和实现

C++面试题(四)——智能指针的原理和实现普通 C 面试时候的一般都是这个套路 1 C 和 C 相比最大的特点 面向对象 封装 继承 多态 2 你知道虚函数吗 实现多态所必须 父类类型的指针指向子类的实例 执行的时候会执行之类中定义的函数 3 析构函数可以是虚函数吗 如果有子类的话 析构函数必须是虚函数 否则析构子类类型的指针时 析构函数有可能不会被调用到 4 多态的实现

C++面试题(四)——智能指针的原理和实现

tanglu2004
http://blog.csdn.net/worldwindjp/

C++面试题(一)、(二)和(三)都搞定的话,恭喜你来到这里,这基本就是c++面试题的最后一波了。

  1答案:智能指针是一个类,这个类的构造函数中传入一个普通指针,析构函数中释放传入的指针。智能指针的类都是栈上的对象,所以当函数(或程序)结束时会自动被释放,

     2, 最常用的智能指针: 

              1)std::auto_ptr,有很多问题。 不支持复制(拷贝构造函数)和赋值(operator =),但复制或赋值的时候不会提示出错。因为不能被复制,所以不能被放入容器中。

              2) C++11引入的unique_ptr, 也不支持复制和赋值,但比auto_ptr好,直接赋值会编译出错。实在想赋值的话,需要使用:std::move。

               例如:

                    std::unique_ptr

p1(new int(5));

                    std::unique_ptr

p2 = p1; // 编译会出错

                    std::unique_ptr

p3 = std::move(p1); // 转移所有权, 现在那块内存归p3所有, p1成为无效的指针.








              3) C++11或boost的shared_ptr,基于引用计数的智能指针。可随意赋值,直到内存的引用计数为0的时候这个内存会被释放。

              4)C++11或boost的weak_ptr,弱引用。 引用计数有一个问题就是互相引用形成环,这样两个指针指向的内存都无法释放。需要手动打破循环引用或使用weak_ptr。顾名思义,weak_ptr是一个弱引用,只引用,不计数。如果一块内存被shared_ptr和weak_ptr同时引用,当所有shared_ptr析构了之后,不管还有没有weak_ptr引用该内存,内存也会被释放。所以weak_ptr不保证它指向的内存一定是有效的,在使用之前需要检查weak_ptr是否为空指针。

     3, 智能指针的实现

      下面是一个基于引用计数的智能指针的实现,需要实现构造,析构,拷贝构造,=操作符重载,重载*-和>操作符。

template 
  
    class SmartPointer { public: //构造函数 SmartPointer(T* p=0): _ptr(p), _reference_count(new size_t){ if(p) *_reference_count = 1; else *_reference_count = 0; } //拷贝构造函数 SmartPointer(const SmartPointer& src) { if(this!=&src) { _ptr = src._ptr; _reference_count = src._reference_count; (*_reference_count)++; } } //重载赋值操作符 SmartPointer& operator=(const SmartPointer& src) { if(_ptr==src._ptr) { return *this; } releaseCount(); _ptr = src._ptr; _reference_count = src._reference_count; (*_reference_count)++; return *this; } //重载操作符 T& operator*() { if(_ptr) { return *_ptr; } //throw exception } //重载操作符 T* operator->() { if(_ptr) { return _ptr; } //throw exception } //析构函数 ~SmartPointer() { if (--(*_reference_count) == 0) { delete _ptr; delete _reference_count; } } private: T *_ptr; size_t *_reference_count; void releaseCount() { if(_ptr) { (*_reference_count)--; if((*_reference_count)==0) { delete _ptr; delete _reference_count; } } } }; int main() { SmartPointer 
   
     cp1(new char('a')); SmartPointer 
    
      cp2(cp1); SmartPointer 
     
       cp3; cp3 = cp2; cp3 = cp1; cp3 = cp3; SmartPointer 
      
        cp4(new char('b')); cp3 = cp4; } 
       
      
     
    
  

      

   

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/205963.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月19日 下午4:47
下一篇 2026年3月19日 下午4:48


相关推荐

  • 匹配滤波器及matlab仿真

    匹配滤波器及matlab仿真随机信号处理笔记:匹配滤波器——南京理工大学顾红老师的《随机信号处理》浅析文章目录随机信号处理笔记:匹配滤波器1.线性滤波器输出端信噪比2.匹配滤波器的传输函数和冲激响应2.1复函数的施瓦兹不等式2.2传输函数求解3.匹配滤波器的性质3.1匹配滤波器的最大峰值信噪比3.2匹配滤波器的幅频特性相频特性3.3匹配滤波器的物理可实现性3.4输出信号和噪声3.5匹配滤波器的时延适应性3.6匹配滤波器的频移不适应性3.7输出信号频谱与输入信号频谱关系4.匹配滤波器的信号处理SNR增益4.1matlab仿真匹配

    2022年6月1日
    51
  • 2022年G3锅炉水处理找解析及G3锅炉水处理考试试卷[通俗易懂]

    题库来源:安全生产模拟考试一点通公众号小程序安全生产模拟考试一点通:G3锅炉水处理找解析是安全生产模拟考试一点通生成的,G3锅炉水处理证模拟考试题库是根据G3锅炉水处理最新版教材汇编出G3锅炉水处理仿真模拟考试。2022年G3锅炉水处理找解析及G3锅炉水处理考试试卷1、【多选题】水垢对锅炉的危害主要有浪费燃料()。(ABD)A、.损坏锅炉受热面B、.降低锅炉出力C、.减少供汽时间D、.缩短锅炉使用寿命E、.提高了环境温度2、【多选题】特种设备作业人员应当遵守()规…

    2022年4月14日
    49
  • 字节跳动发布豆包 1.5 深度思考模型,同时升级文生图模型

    字节跳动发布豆包 1.5 深度思考模型,同时升级文生图模型

    2026年3月12日
    2
  • pycharm使用技巧及常用快捷键_单元格设置的快捷键是什么

    pycharm使用技巧及常用快捷键_单元格设置的快捷键是什么1.下载安装PyCharm官方下载地址:https://www.jetbrains.com/pycharm/download/index.html#section=windows安装完成后在弹出的界面中选择新建一个工程:2.首次使用首次使用需要配置一下控制台,才能正常调试python点击灰色的倒三角,选择“EditConfigur…

    2022年8月27日
    7
  • Springboot+druid数据库连接池使用「建议收藏」

    Springboot+druid数据库连接池使用「建议收藏」1.为什么要使用数据库连接池使用数据库连接池主要考虑到程序与数据库建立连接的性能。创建一个新的数据库是一个很耗时的过程,在使用完之后,可能还需要不断的释放建立的连接,对资源的损耗大。而采用数据库连接池之后,首先就创建了固定数量的数据库连接,需要用的时候使用即可。当然,这样做的一个缺点是,可能某些时候完全没有数据库请求,但是也保持了数据库的最小连接数。浪费了…

    2025年11月25日
    5
  • python保留小数位的两种方法总结[通俗易懂]

    python保留小数位的两种方法总结[通俗易懂]题目背景:方法一:format函数format有不同用法,代码如下,前者使用了占位符{},使用占位符可以同时输出多个,后者一次只能输出一个importmathres=math.sqrt(a**2+b**2)#使用占位符print(‘{:.3f}’.format(res))#可以同时输出多个print(‘{:.3f}\n{:.2f}’.format(res,res))#不使用占位符只能输出一个print(format(res,’.3f’))运行结果:方法二:’%

    2022年8月12日
    6

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号