作者:几冬雪来
时间:2023年5月19日
内容:C++——内存管理+模块
目录
前言:
1.new和delete操作自定义类型:
operator new/delete:
定位new表达式(placement-new):
malloc/free和new/delete区别:
2.模板:
结尾:
前言:
在上一篇博客中我们成功的对我们的类和对象的知识进行了收尾工作,并且加入了内存管理这个新的知识点,今天就进一步对其进行讲解。
1.new和delete操作自定义类型:
在上一篇博客中,我们引入的新的操作符——new和delete。
并且对它们两个新操作符的作用,写法还有和C语言中malloc,realloc。calloc的哪里有所不同都一一进行了讲解。
在这里我们可以看出来。
new的时候这里我们的代码会去调用构造函数,同时在delete的时候也会去调用我们的析构函数。
因此以后绝大部分地方我们都会用new和delete来代替我们的free和malloc。
同时在new对数组进行初始化的时候,如果在这里我们是多参数的情况就需要这样书写。
同样的在这里我们也会对其进行优化。
当然,在一般情况下如果我们像上面这样写的话,只给3个是不行的。
这里我们就需要默认构造来对其进行实现才能正常使用,如果没有默认构造我们就要用4个。
对比下来在动态申请内置类型的数据的时候。
new/malloc除了用法上,其他方面并没有什么区别。
但是在动态申请自定义类型的数据的时候。
new/malloc除了用法上,还有一个中大区别,new和delete会调用构造函数初始化,析构函数情理。
operator new/delete:
在讲解了我们的new和delete之后。
接下来我们就来讲解两个操作符之间的底层构造。
在这里我们的operator new/delete并不是直接运算符重载,而是全局函数,是库里面的函数。
new它的底层和malloc的底层是大致相同。
同时我们的delete也是和free一样。
因此我们可以在代码中对free和malloc进行修改。
从这里也可以空间,在用法上我们的operator new和malloc是一样的。
但是它们所产生的价值却是不一样的。
那么我们就来对其讲一讲。
这里在我们malloc的时候如果我们申请空间失败的话,在这里是返回空。
这一点和我们C++中的new有所不同。
在这里C++中,如果面向对象语言处理失败,不喜欢用返回值,更建议使用抛异常。
而我们的异常是要被捕获的。
这也就解释了为什么我们的operator new在全局中,因为它是独属于给new进行使用的。
同时通过上面的话我们也可以看出。
new在开空间的时候先去调用operator new,然后operator new再去调用我们的malloc。
但是在需要申请一个堆上的栈对象delete又是相反,我们是先调用析构再释放空间。
这里是3块空间,一个是指针,在我们malloc函数的栈里面,一个是栈对象,它在堆上,在我们的栈对象中有一个指针指向我们的空间还是在栈对象上。
通过上面的讲解,我们也可以可以判断出来,C语言和C++相对比除了有用法上的区别。
还有失败时候也存在区别。
那么从此以后,我们就不用像C语言那样进行判断是否失败返回为空的操作,而是用到我们的捕获。
也就是我们这里的try...catch,这里我们就简单的看一下它的写法即可。
在上面说过,现在我们可以用new去替代我们的malloc,但是这并不意味着malloc就毫无作用了,它只是隐藏在里面使用了。
定位new表达式(placement-new):
接下来我们来了解一下new的其他的用法。
对一块已有的空间调用构造函数。
在这里我们就可以显示的调用构造函数。
这里我们的p1是内置类型不会自动的调用析构,所以我们也要显示调用析构函数。
但是这种方法在我们现在看来并没有什么用。
这里如果对其使用的话就要了解到我们的池化技术。
而我们的池化技术包括了:内存池,连接处,线程池等等。
在这里我们的池就是用来方便我们的。
简单的举个例子:以前我们每次要买笔记本,笔什么的都要先去找到父母要到钱,但是我们的池化技术就类似把买文具的钱放在某个盒子里,放在一固定位置,需要的时候就直接去拿,这里就能方便我们自己。
malloc/free和new/delete区别:
2.模板:
讲解完了内存管理,接下来我们就要讲解C++的一个非常非常重要的知识点——模板。
在以后我们学习很多知识都需要用到模板。
像我们这里如果要去执行不同类型的值的互换,那么在这里我们就需要写很多个函数对其一一匹配。
那么在这里在这里我们就要使用到我们的模板。
在模板这里我们又将其分为函数模板和类模板。
在这里就是我们模板的代码书写。
接下来我们就来写一个完整的代码对其进行更加详细的分析。
这里我们就通过了模板来使值进行了交换。
同时在使用了模板之后,上面的3种不同类型交换值的写法我们就可以不用写了。
但是这里要知道的一个点是:
虽然我们调用了模板,可以在这里我们并非调用的同一个函数。
这里我们的模板通过判断传的参数是整形,浮点型来推演出我们的函数。
这一个过程被我们称为模板的实例化。
但是这里我们实际调用的并不是模板,而是模板生成的函数,最后还是编译器生成的函数。
同样的这里我们也可以来交换日期类函数。
结尾:
到这里我们又小小的结束了一个小板块的知识,也学习了下一个板块的些许内容。在这里我们的类和对象,动态管理都是十分重要的知识板块,有时间一定要去复习和做题去巩固知识。最后希望这篇博客能带来帮助。