C++内存管理/函数模板/类模板

news2024/10/5 15:03:53

一、C++内存管理

C++中内存基本形式与C语言类似,可以参考下图。

X64环境下总共大小为8G,X86环境下为4G。

1、内核空间:用户不能读写,但要占用一定空间。

2、栈区:以开辟、销毁栈帧形式运行,主要应用于局部变量和函数栈帧。以及在函数递归中,反复多次开辟、销毁栈帧,使得空间有能够重复利用的可能(死递归时栈溢出)。

向下增长。

但这种向下增长在具体情景下也会受到编译器优化的制约。 

3、堆区:用来动态内存分配的,所占空间较大。VS的X86环境下大约为2G,占一半左右。

4、数据段:存储  静态/全局变量

5、代码段:存储全局函数,类的成员函数。一些常量/字符串,且不能被修改。

二、new/delete

与C的区别

malloc/free和new/delete的共同点是:都是从堆上申请空间,并且需要用户手动释放。不同的地
方是:
1. malloc和free是函数,new和delete是操作符
2. malloc申请的空间不会初始化,new可以初始化
3. malloc申请空间时,需要手动计算空间大小并传递,new只需在其后跟上空间的类型即可,
如果是多个对象,[]中指定对象个数即可
4. malloc的返回值为void*, 在使用时必须强转,new不需要,因为new后跟的是空间的类型
5. malloc申请空间失败时,返回的是NULL,因此使用时必须判空,new不需要,但是new需
要捕获异常
6. 申请自定义类型对象时,malloc/free只会开辟空间,不会调用构造函数与析构函数,而new
在申请空间后会调用构造函数完成对象的初始化,delete在释放空间前会调用析构函数完成
空间中资源的清理

用法:

new/delete均是操作符,不再是malloc和free这样的函数。

直接用 new+类型即可,直接定义出对象,这个类型可以是内置类型也可以是自定义类型,可以传参()/使用缺省值,还可以直接定义出多个对象[]。

new可以直接得到调用构造函数初始化了的对象,使用起来更加方便。

 这里我使用了缺省值创建了10个A类型的对象,会分别调用10次构造函数,每一个对象里的_a都会被初始化为10.

 传参/匿名对象时同样涉及编译器优化的问题,连续的拷贝构造/构造会被优化为直接构造。

底层:

 new是开空间+调用构造函数对对象进行初始化,由于面向对象语言特性,需要抛异常,又封装了一层operator new(为全局函数,不是运算符重载)

operator new 实际也是通过malloc来申请空间,如果malloc申请空间成功就直接返回,否则执行用户提供的空间不足应对措施,如果用户提供该措施就继续申请,否则就抛异常。operator delete 最终是通过free来释放空间的。

应用在自定义类型:

 new一个Stack类型时,先开空间,然后调用构造函数,对于Stack的成员变量进行初始化,如果有深拷贝,这个深拷贝也可以被完成。

delete一个Stack类型时,先调用析构函数,进行资源清理,其中深拷贝的部分在析构函数中完成清理,最后再将这个Stack对象的空间给释放。

三、函数模板

C++中类class的引入,使得类型不仅仅是内置类型,更多的是自定义类型

而由于自定义类型的不确定性,会出现无数多个自定义类型,我们就需要一套通用于所有类型的规则,只需要用一个参数/变量来区分这个类型即可。

例如Swap函数,可以交换内置类型,在C++中,我们希望它也可以做到自定义类型的交换。通过之前函数重载的学习,我们可以通过多次函数重载来实现,但是会有下面2个问题。

1. 重载的函数仅仅是类型不同,代码复用率比较低,只要有新类型出现时,就需要用户自己增加对应的函数。
2. 代码的可维护性比较低,一个出错可能所有的重载均出错。(且如果涉及函数功能的变化,每个类型的重载函数都需要修改)

因此,在C++中,我们升级了编译器。可以完成泛型编程。

泛型编程:编写与类型无关的通用代码,是代码复用的一种手段。模板是泛型编程的基础。
即指定某些参数(来替代类型)交给编译器,使得编译器得到一个模板,用户只要再通过传参等方式,使得编译器确定这个参数,就能自动生成相应的模板函数或模板类。(函数模板和类模板是模板,模板函数/模板类是编译器生成的具体的函数/类)

函数模板的实例化:

 通过反汇编可以看出,编译器确实  实例化出了2个不同的函数。

编译器必须确定模板参数:

隐式实例化:

隐式即不指定模板参数T的类型,通过编译器自动推导而得出T的类型(无歧义)。

 只有1个模板参数T,传入int类型的a1,和double类型的d1,因此编译器推导不出模板参数T的具体类型,就会报错。

显示实例化:

这里通过<int>和<double>指定了模板参数T的类型,就会使编译器相应的生成并调用对应的Add函数。

 

也可以定义2个模板参数T1和T2,这样就不用管传入的2个参数类型是否相同的。

不过,如果要返回T1或者T2,实参的顺序还是有影响的。 

最后这种情况,由于模板参数T不是通过传参来确定的,就必须通过<>中提前确定T的类型。

模板参数的匹配原则:

1. 一个非模板函数可以和一个同名的函数模板同时存在,而且该函数模板还可以被实例化为这个非模板函数。

2. 对于非模板函数和同名函数模板,如果其他条件都相同,在调动时会优先调用非模板函数而不会从该模板产生出一个实例。如果模板可以产生一个具有更好匹配的函数, 那么将选择模板。

3. 模板函数不允许自动类型转换,但普通函数可以进行自动类型转换。

 四、类模板 

定义:

在类的前面,加上template<>,<>内加上这个类中需要用到的模板参数,可以有多个,如下。

 

 栈本身的实现是相同的,但栈中要存储什么元素是事先不知道的。

C语言中需要使用typedef定义同样的类型datatype,但是当我们需要同时使用int栈和double栈时,就必须定义StackInt和StackDouble了。

而在C++中,可以直接用一个模板参数T,来表示要存储的元素类型。

定义声明分离:

 定义内,如果要用到模板参数,需要在前面使用template<T,P,Q>指定,它们的作用范围就是这个函数的实现范围。

对于类模板,类名和类型是不同的。类模板名字不是真正的类,而实例化的结果才是真正的类

Stack不为类型,仅为类名,Stack<int>和Stack<double>实例化出的类才是真正的类型。

因此在类外定义成员函数,指定类域时,必须使用class的类型。(类同名时无法区分,必须要通过模板参数T区分,因此指定类域必须通过T)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/548847.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

chatgpt赋能Python-python3_choice

Python3中的choice()函数&#xff1a;一种简单而有趣的随机选择方式 在Python3中&#xff0c;choice()函数是一个常见的随机模块。它允许我们从一个序列中随机选择一个元素。这在程序中经常用于生成一些需要随机展示的数据。本文将介绍Python3中的choice()函数&#xff0c;并探…

00.SpringCloud服务调用方式

服务调用方式 RPC和HTTP 无论是微服务还是SOA&#xff0c;都面临着服务间的远程调用。那么服务间的远程调用方式有哪些呢&#xff1f; 常见的远程调用方式有以下2种&#xff1a; RPC&#xff1a;Remote Produce Call远程过程调用&#xff0c;类似的还有 。自定义数据格式&am…

合合信息亮相CCIG2023:多位大咖共话智能文档未来,文档图像内容安全还面临哪些技术难题?

近日&#xff0c;中国图象图形大会&#xff08;CCIG 2023&#xff09;&#xff08;简称“大会”&#xff09;在苏州圆满落幕。本届大会以“图象图形向未来”为主题&#xff0c;由中国科学技术协会指导&#xff0c;中国图象图形学学会主办&#xff0c;苏州科技大学承办&#xff…

干货 | 利用SPSS进行高级统计第一期(更新)

Hello&#xff0c;大家好&#xff01; 这里是壹脑云科研圈&#xff0c;我是喵君姐姐~ 在之前的文章中&#xff0c;我们以此介绍了如何利用SPSS进行高级统计分析&#xff0c;内容包括&#xff1a; (1)描述性统计表格模板、卡方&T检验、相关&回归分析 (2)中介、多重中…

MD5_buuctf

概念 MD5信息摘要算法&#xff0c;一种被广泛使用的密码散列函数&#xff0c;可以产生出一个128位&#xff08;16字节&#xff09;的散列值&#xff08;hash value&#xff09;&#xff0c;用于确保信息传输完整一致。 MD5算法具有以下特点&#xff1a; 压缩性&#xff1a;任意…

一次失败的面试经历:我只想找个工作,你却看不起我?还用面试题羞辱我...

这段时间都说难找工作&#xff0c;没有面试机会。面对如此严峻的形式&#xff0c;很多软件测试人员都希望能拿一个满意的高薪offer&#xff0c;但是随着招聘职位的不断增多&#xff0c;面试的难度也随之加大&#xff0c;而面试官更是会择优录取 我最近为面试已经焦头烂额了&am…

循坏队列+OJ题之设计循环队列

生命不是要等待风暴过去&#xff0c;而是要学会在风暴中跳舞。 ——卡莉尔吉布朗目录 &#x1f33a;前言&#xff1a; &#x1f341;一.循环队列是什么&#xff1f; &#x1f34f;二.循环队列有什么作用&#xff1f; &#x1f340;三.OJ题之设计循环队列 1…

C++(3):字符串、向量和数组

命名空间的 using 声明 using namespace::name;1.每个名字都需要独立的 using 声明&#xff1b; 2.头文件不应包含 using 声明&#xff1a; 因为头文件的内容会拷贝到所有引用它的文件中去&#xff0c;如果头文件里有某个using声明&#xff0c;那么每个使用了该头文件的文件就…

Apache Kafka - 重识Kafka生产者

文章目录 概述Kafka 生产者Kafka 生产者工作原理如何使用 Kafka 生产者 生产者配置项&#xff08;核心&#xff09;导图总结 概述 Kafka 生产者是 Apache Kafka 中的一个重要组件&#xff0c;它负责将数据发送到 Kafka 集群中。在实时数据处理和流式处理应用程序中&#xff0c…

如何自建个人音乐播放器Navidrome

文章目录 1. 前言2. Navidrome网站搭建2.1 Navidrome下载和安装2.1.1 安装并添加ffmpeg2.1.2下载并配置Navidrome2.1.3 添加Navidrome到系统服务 2.2. Navidrome网页测试 3. 本地网页发布3.1 cpolar的安装和注册3.2 Cpolar云端设置3.3 Cpolar本地设置 4. 公网访问测试5. 结语 转…

【总结】Nupmy1

Nupmy numpy的核心是名为ndarray的数据类型&#xff0c;它代表多维数组&#xff0c;封装了操作数据的运算和方法 1. 创建数组对象 1.1 方法1:array 通过array将list转换成数据对象 # 通过array将list转换成数据对象 array1np.array([1,2,3,4,5]) array1 # array([1, 2, 3,…

Nginx + fastCGI 实现动态网页部署

简介 本文章主要介绍下&#xff0c;如何通过Nginx fastCGI来部署动态网页。 CGI介绍 在介绍fastCGI之前先介绍下CGI是什么。CGI : Common Gateway Interface&#xff0c;公共网关接口。在物理层面上是一段程序&#xff0c;运行在服务器上&#xff0c;提供同客户端HTML页面的…

测试理论----Bug的严重程度(Severity)和优先级(Priority)的分类

【原文链接】测试理论----Bug的严重程度&#xff08;Severity&#xff09;和优先级&#xff08;Priority&#xff09;的分类 一、Bug的严重程度&#xff08;Severity&#xff09; Bug的Severity&#xff08;严重程度&#xff09;指的是一个Bug对软件系统功能影响的程度&#…

Java常用工具之Collections

目录 一、排序操作二、查找操作三、同步控制三、不可变集合四、其他五、CollectionUtils&#xff1a;Spring 和 Apache 都有提供的集合工具类六 、小结 Collections 是 JDK 提供的一个工具类&#xff0c;位于 java.util 包下&#xff0c;提供了一系列的静态方法&#xff0c;方便…

2023河海大学846软件工程学硕考研高分上岸经验分享

大家好&#xff0c;我是陪你考研每一天的大巴学长。 大巴学长为大家邀请到了2023年846软件工程学硕刚刚上岸的学长&#xff0c;为大家分享一下他的考研经验&#xff0c;经验里详细介绍了各科的复习方法&#xff0c;很有参考意义。 希望对大家有所借鉴和帮助&#xff0c;在此向…

栈实现队列(继续细起来啊)

生命不是要等待风暴过去&#xff0c;而是要学会在风暴中跳舞。 ——卡莉尔吉布朗目录 &#x1f341;一.栈实现队列 &#x1f340;二.使用两个栈实现队列的功能 &#x1f33c;1.在队列的结构体中创建两个栈 &#x1f681;2.创建一个队列的结构体指针 &#x1f309;3…

云计算中的大数据处理:尝试HDFS和MapReduce的应用

云计算中的大数据处理&#xff1a;尝试HDFS和MapReduce的应用 文章目录 云计算中的大数据处理&#xff1a;尝试HDFS和MapReduce的应用一、前言二、第一题1、命令方式2、java API方式 三、第二题1、创建CSV文件并将其上传到HDFS2、编写利用MapReduce框架的java代码3、打包java项…

【设计模式与范式:创建型】41 | 单例模式(上):为什么说支持懒加载的双重检测不比饿汉式更优?

从今天开始&#xff0c;我们正式进入到设计模式的学习。我们知道&#xff0c;经典的设计模式有 23 种。其中&#xff0c;常用的并不是很多。据我的工作经验来看&#xff0c;常用的可能都不到一半。如果随便抓一个程序员&#xff0c;让他说一说最熟悉的 3 种设计模式&#xff0c…

Kelvin和Rossby波 Part-2(浅水方程)

在前面博主有篇关于Kelvin和Rossby波的简要介绍&#xff0c;见下&#xff1a; Kelvin和Rossby波 Part-1&#xff08;简要介绍&#xff09; 开尔文波&#xff08;Kelvin Wave&#xff09;是发生在大气或海洋中的&#xff0c;迎向地形边界&#xff08;例如海岸线&#xff09;平衡…

回顾2023年计算机专业学生卑微求职 / 申博血泪史

0.前言 2023年是悲惨的一年&#xff0c;各个行业都在卷中卷。同时对于个人来说&#xff0c;2023年也是最忙碌的一年&#xff0c;不仅面临毕业&#xff0c;而且面临工作/读博&#xff0c;随便挑出一件&#xff0c;都是一件耗时耗力的事。相信大家也从网络上看到了很多的帖子或者…