前面小哥跟大家聊了一下C++一般是如何规避掉原生数组访问容易越界的问题,看完以后应该觉得很简单吧,把原生数组通过类来进行一次封装并重载相应的操作符,这样在使用上几乎与原生数组没有太大差异,但是通过访问类就没有那么直接访问原生数组那么直接,在访问过程中留给程序员一些处理接口,从而可以提前获得相关异常,这样在效率上肯定也是大打折扣。玩MCU的伙计,这样的处理方式就很难吃得消了,对于越界类似问题几乎只能自己去把控了。除了数组越界问题,还有一类bug是大家常遇到的,那就是动态内存的泄露与多次释放问题,该问题在MCU开发中出现的不多,毕竟大家用得少,不过在上层一点的开发中算是经常遇到的,那么今天聊聊此类问题C++会用什么好的办法来进一步规避。在C或者C++中都会使用指针来标识动态申请的内存空间,所以是否可以从指针入手来处理该问题呢?便引出了智能指针的概念。什么是智能指针呢?一看'智能'两个字大家可能就慌了,肯定很难,其实所谓的智能指针就是一种类模板,而类模板其实本质上就是类,其实智能智能就可以认为是一种指针类,与前面介绍的数组类类似。
智能指针的实现讨论与前面的数组类是类似的,主要就是把原生指针重新封装了一下,下面简单的使用类模板来模拟智能指针的实现过程,
下面是参考代码 :
1、下图是智能指针类模板的定义,以原生指针作为核心数据成员,然后分别实现构造和析构来进行动态内存的申请与分配,通过重载指针相关操作符来达到偷梁换柱的目的。
2、下面是对应成员函数的具体实现,也是对应的类模板定义,看起来挺简单的,如果真的要写起来还是有非常多地方需要注意,比如const_cast的强制类型转换,重载*和->其返回值问题,前者返回指针内存的引用,后者则是直接返回指针。3、下面是测试程序,使用方法与之前跟大家介绍的类模板的使用语法是一致的,并且你也会发现其智能指针的使用与原生指针的使用几乎没有什么差异。
4、下面是测试程序编译运行以后的输出结果,与我们预期结果是一致的。所以智能指针仅仅只是封装了原生指针的一种类模板,通过利用好类的构造和析构函数来进行动态内存的释放等处理,通过重载运算符来使得这些类的使用方式与原生指针在用法上几乎一致。在这个过程中当然C++编译器为源代码做了非常多的工作,相应的其编译器也会比纯C要复杂一些。同时在一些标准库中都会提供一些智能指针(类模板)供编程人员直接使用,比如memory头文件中常用的三种智能指针:shared_ptr,unique_ptr,weak_ptr。他们各有自己的特点,注意一下使用条件和功能应该就很好理解了。
这里小哥就介绍了一下关于C++规避动态内存泄露与多次释放 ,希望本文能够对你有帮助,该系列还会持续更新,大家可以持续关注~