C++动态内存区域划分、new、delete关键字、泛型编程、函数模版、类模版

目录

一、C/C++中程序的内存区域划分

为什么会存在内存区域划分?

二、new关键字

1、内置类型的new/delete使用方法:

2、new和delete的本质

3、常见面试题——malloc/free和new/delete的区别

三、模版

1、泛型编程

2、函数模版

(1)、引言

(2)、概念

3、模版原理

4、模版的实例化

5、类模版

6、匹配调用规则:

7、类模板注意事项:


一、C/C++中程序的内存区域划分

为什么会存在内存区域划分?

因为不同数据有不同的存储需求,各区域满足不同的需求。

例如:

(1)、一些临时变量,局部变量存储在栈区

(2)、常用数据结构或一些算法(如归并排序)中会用到动态内存开辟,该内存是在堆区申请。

(3)、全局变量、静态变量存储在数据段(静态区)。

(4)、一些只读数据,如字符常量、可执行代码(指令)存储在代码段(常量区)。

二、new关键字

 C语言中动态内存管理方式使用malloc/calloc/realloc/free函数来实现,C语言内存管理方式在C++中可以继续使用,但有些地方就无能为力,而且使用起来比较麻烦,因此C++又提出了自己的内存管理方式:通过newdelete操作符进行动态内存管理。

1、内置类型的new/delete使用方法:

	//动态申请一个int型
	int* a = new int;

	//动态申请一个int型,并初始化为10
	int* a1 = new int(10);

	//动态申请一个int型数组
	int* arr1 = new int[10];
	
	//动态申请一个int型数组,并初始化
	int* arr2 = new int[3] {1, 2, 3};

	//若为完全初始化,则后面的值会默认初始化为0
	int* arr3 = new int[10] {1, 2, 3};

	//每new一个变量,用完后一定要delete
	delete a;
	delete a1;
	//注意数组的区别
	delete[] arr1;
	delete[] arr2;
	delete[] arr3;

注意:使用new未初始化时,不会有默认值,而是随机值。

2、new和delete的本质

new的本质是为了解决动态申请的自定义类型对象的初始化问题。

因为C语言中malloc函数不能给自定义类型进行初始化:

	//malloc不能给自定义类型初始化
	A* p1 = (A*)malloc(sizeof(A));

所以这时就可以用new和delete:

(1)、new的本质:开空间+调用构造函数初始化;

(2)、delete的本质:先调用析构函数+释放空间。

如下:

	//new给自定义类型初始化
	//调用默认构造函数
	A* p2 = new A();
	//调用带参数构造函数
	A* p3 = new A(1);

	//给对象数组初始化
	//(1)、有名对象
	A aa1, aa2, aa3;
	A* arr1 = new A[3]{ aa1,aa2,aa3 };
	//(2)、匿名对象
	A* arr2 = new A[3]{ A(),A(),A()};
	//(3)、隐式类型转换
	A* arr3 = new A[3]{ 1,2,3 };

注意:

(1)、内置类型的底下申请释放,new和malloc除了用法上,没有区别;

(2)、malloc申请失败会返回NULL,而new申请失败会抛异常;

3、常见面试题——malloc/free和new/delete的区别

从用法+原理角度区分:

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

三、模版

1、泛型编程

泛型编程通俗来讲就是写跟具体类型无关的代码,广泛的编程。是代码复用的一种手段。模板是泛型编程的基础。

2、函数模版

(1)、引言

我们以交换函数为例,看下列代码:

void Swap(int& p1, int& p2)
{
	int tmp = p1;
	p1 = p2;
	p2 = p1;
}

void Swap(char& p1, char& p2)
{
	char tmp = p1;
	p1 = p2;
	p2 = p1;
}

void Swap(double& p1, double& p2)
{
	double tmp = p1;
	p1 = p2;
	p2 = p1;
}

这是用函数重载的知识,但函数重载也有不好的地方:

1. 重载的函数仅仅是类型不同,代码复用率比较低,只要有新类型出现时,就需要用户自己增加对应的函数。
2. 代码的可维护性比较低,一个出错可能所有的重载均出错。
正如上述各函数,我们发现好像只有类型不同,这时我们就可以用模版来减少代码的冗余。
(2)、概念
函数模板代表了一个函数家族,该函数模板与类型无关,在使用时被参数化,根据实参类型产生函数的特定类型版本。
格式:
template<typename T1, typename T2,......,typename Tn>
返回值类型 函数名(参数列表){}
例如上述代码,我们可以写成:
template<typename T>

void Swap(T& p1, T& p2)
{
	T tmp = p1;
	p1 = p2;
	p2 = tmp;
}

当有多种类型时,就可以写多个typename(或class):

注意:

typename是用来定义模板参数关键字,也可以使用class(切记:不能使用struct代替class)

3、模版原理

注意一点:
模版处只有一个函数,为什么会是调用的两个函数?这就是模版的原理所造成的现象:
原理:
函数模板是一个蓝图,它本身并不是函数,是编译器用使用方式产生特定具体类型函数的模具。所以其实模板就是将本来应该我们做的重复的事情交给了编译器。
在编译器编译阶段,对于模板函数的使用,编译器需要根据传入的实参类型来推演生成对应类型的函数以供 调用。比如:当用double类型使用函数模板时,编译器通过对实参类型的推演,将T确定为double类型,然 后产生一份专门处理double类型的代码,对于字符类型也是如此。

4、模版的实例化

用不同类型的参数使用函数模板时,称为函数模板的实例化。模板参数实例化分为:隐式实例化和显式实例化。
模版参数语法很类似函数参数,只是函数参数定义的是形参对象,而模版定义的是类型。

(1)、推演实例化:例如上述内容,是编译器自己识别模版是什么类型,就叫推演实例化。

(2)、显示实例化:

//单类型模版显示调用
Swap<int>(1, 1);
//多类型模版显示调用
Test<int, double>(1, 5.5);

有一些情况只能用显示实例化,比如无参函数,传不了参数,就不能靠推演确定类型,这时只能显示实例化模版:

5、类模版

(1)、类模版定义格式

template<class T1, class T2, ..., class Tn>
class 类模板名
{
// 类内成员定义
};

特别注意:类模版必须显示实例化:

然后模版与类之间不能存在函数使用模版,同理想要函数模版,中间也不能穿插类使用模版。

6、匹配调用规则:

1、有现成的函数可以匹配就调用现成。

2、有合适的就调用合适的,没有就将就。

7、类模板注意事项:

(1)、使用类模版后,当成员函数的声明与定义分开写时,会有改变:

template<class T>
class Test
{
public:
	//构造函数
	//声明
	Test(T i);
private:
	int _i;
};

//定义
template<class T>
Test<T>::Test(T i)
{
	T tmp;
}

(2)、特别注意:

普通类:类名就是类型。

类模板实例化的类:类名不是类型,类名<数据类型>才是整个类的类型。

也就是说:显示实例化类模板的类型不同,它们就是不同的类:

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【C语言】6.C语言VS实用调试技巧(2)

文章目录 6.调试举例17.调试举例28.调试举例3&#xff1a;数组9.编程常⻅错误归类9.1 编译型错误9.2 链接型错误9.3 运⾏时错误 – 6.调试举例1 求 1!2!3!4!…10! 的和。 int main() {int n 0;int i 0;int ret 1;int sum 0;for (n 1; n < 3; n) {for (i 1; i < …

LBSS138LT1G 丝印J1 SOT-23 N沟道 50V/200mA 贴片MOSFET

LBSS138LT1G的应用领域广泛&#xff0c;主要因为它是一种N沟道金属氧化物半导体场效应晶体管&#xff08;MOSFET&#xff09;&#xff0c;具有低电荷、快速开关速度和高阻断特性。以下是一些典型的应用领域&#xff1a; 1. 消费电子产品&#xff1a;LBSS138LT1G常用于电视、音响…

四川景源畅信:如何更好的为抖音小店做引流?

在数字化营销的浪潮中&#xff0c;抖音小店作为新兴的电商形态&#xff0c;正以其独特的社交属性和流量优势吸引着众多商家的目光。如何为抖音小店引流&#xff0c;成为许多店主心中的疑问。本文将深入探讨有效提升店铺流量的策略&#xff0c;助你在抖音平台上快速崛起。 一、内…

【漏洞复现】Secnet-智能路由系统 actpt_5g.data信息泄露

0x01 产品简介 Secnet安网智能AC管理系统是广州安网通信技术有限公司(简称“安网通信”)的无线AP管理系统 0x02 漏洞描述 Secnet智能路由系统 acipt 5g.data 接口存在信息泄露漏洞&#xff0c;未经身份验证的远程攻击者可以利用此漏洞获取系统账户名密码等重要凭据&#xff…

印染工厂5G智能制造数字孪生可视化平台,推进行业数字化转型

印染工厂5G智能制造数字孪生可视化平台&#xff0c;推进行业数字化转型。印染工厂正迈入一个全新的时代&#xff0c;这个时代以5G智能制造数字孪生可视化平台为核心&#xff0c;推动整个行业的数字化转型。不仅是一场技术革命&#xff0c;更是一次产业变革&#xff0c;为印染工…

在微信小程序项目中安装和使用 Vant 组件库

vant Wwapp 小程序开发组件库官网 Vant Weapp - 轻量、可靠的小程序 UI 组件库 安装 Vant 组件库 1.在微信小程序项目文件目录的空白位置右键&#xff0c;选择在外部终端窗口中打开 2在命令行输入如下命令&#xff08;在项目中创建包管理配置文件 package.json&#xff09; …

AI预测体彩排3采取878定位大底=23策略+杀断组+杀组选+杀和尾+杀和值012缩水测试5月15日预测第1弹

昨天与一位玩排3的彩友通过视频直播的形式聊了下&#xff0c;受益匪浅&#xff0c;给我提供了一些比较有价值的建议&#xff0c;比如&#xff0c;对于878的定位策略&#xff0c;方向是没问题的&#xff0c;但是8783的话&#xff0c;还是缺乏一定的命中率&#xff0c;如果87823&…

【算法学习】拓扑排序

文章目录 拓扑排序课程表 拓扑排序 算法原理&#xff1a; 1.先找出图中入度为0的点&#xff0c;将该点加入到队列中 2.队列不为空时&#xff0c;拿出队头元素加入到最终结果 3.再遍历该点的邻接阵&#xff0c;将连接该点的点的入度全部减减 4.判断减减的点是否为入度为0&#…

亚马逊跨境电商平台优势凸显,武汉星起航解析助力卖家把握商机

在全球电商市场的激烈竞争中&#xff0c;亚马逊凭借其独特的优势和卓越的运营能力&#xff0c;成为众多卖家首选的跨境电商平台。武汉星起航作为深耕亚马逊跨境电商领域的领军企业&#xff0c;对亚马逊平台的优势有着深刻的理解和独到的见解。本文将重点探讨亚马逊跨境电商平台…

降Compose十八掌之『亢龙有悔』

公众号「稀有猿诉」 原文链接 降Compose十八掌之『亢龙有悔』 Jetpack Compose是新一代的声明式的UI开发框架&#xff0c;由Google在2019年推出&#xff0c;最初是作为Android的新式UI开发框架&#xff0c;但它本质是一个声明式UI开发框架&#xff0c;并不受制于底层的平…

腾讯云环境安装单机版minio

Minio 下载安装 wget https://dl.min.io/server/minio/release/linux-amd64/minio修改minio 文件为可执行文件 chmod x minio3、启动&#xff0c;随机端口启动 ./minio server /data/miniodata # 或者指定密码执行 MINIO_ACCESS_KEYmyminioadmin MINIO_SECRET_KEYmyminioadm…

精酿啤酒:品质的保障与消费者的信赖

在啤酒市场中&#xff0c;Fendi club啤酒以其卓着的品质和消费者的信赖赢得了广泛的认可。作为精酿啤酒的品牌&#xff0c;Fendi club啤酒始终坚持对品质的严格把控&#xff0c;为消费者带来放心的口感体验。 品质的保障源于Fendi club啤酒对原料的严谨挑选和加工。他们深知&a…

在大型项目上,Python 是个烂语言吗?

在开始前我有一些资料&#xff0c;是我根据网友给的问题精心整理了一份「Python的资料从专业入门到高级教程」&#xff0c; 点个关注在评论区回复“888”之后私信回复“888”&#xff0c;全部无偿共享给大家&#xff01;&#xff01;&#xff01; python项目超过5万行&#x…

STM32的FLASH学习笔记

不同型号的 STM32&#xff0c;其 FLASH 容量也有所不同&#xff0c;最小的只有 16K 字节&#xff0c;最大的则达到了1024K 字节。大容量产品的闪存模块组织如图所示&#xff1a; STM32 的闪存模块由&#xff1a;主存储器、信息块和闪存存储器接口寄存器等 3 部分组成。 ​ ①主…

pikachu靶场通关之暴力破解token防爆破

这里写pikachu靶场token防爆破的第二种解法 用python脚本跑&#xff0c;下面是代码 import requests from bs4 import BeautifulSoup# url填自己的url url http://localhost:8086/pikachu-master/vul/burteforce/bf_token.php # 取出账号字典里的值&#xff0c;1.txt就是账号…

docker安装minio附带图片

1.拉镜像 docker pull minio/minio 2.创建挂载点目录 mkdir -p /usr/local/minio/config mkdir -p /usr/local/minio/data 3.创建minio容器 docker run \ -p 19000:9000 \ -p 9090:9090 \ --nethost \ --name minio \ -d --restartalways \ -e "MINIO_ACCESS_KEYmini…

k8s 二进制安装 优化架构之 部署负载均衡,加入master02

目录 一 实验环境 二 部署 CoreDNS 1&#xff0c;所有node加载coredns.tar 镜像 2&#xff0c;在 master01 节点部署 CoreDNS 3&#xff0c; DNS 解析测试 4&#xff0c; 报错分析 5&#xff0c;重新 DNS 解析测试 三 master02 节点部署 1&#xff0…

[HNCTF 2024] crypto/pwn

周日的比赛&#xff0c;赛后拿别人的WP又作了俩&#xff0c;最后一个题也是没弄懂&#xff0c;先记一下吧。 Crypto EZmath 一个简单的函数题。在sagemath里有个two_squares函数&#xff0c;可以从平方和恢复两个规模相近的数。这种比较适合于RSA里的p,q。另外未知的e用来猜…

mybatis:Spring junit 测试报错:Failed to load ApplicationContext

Spring junit 测试报错&#xff1a;Failed to load ApplicationContext 解决方法&#xff0c;修改mybatis版本&#xff0c;版本过高导致无法加载依赖

GDPU 竞赛技能实践 天码行空 期末小测

1. 除法&#xff08;原题&#xff09; &#x1f468;‍&#x1f3eb; 实验二&#xff1a;1.简单枚举 输入正整数n&#xff0c;按从小到大的顺序输出所有形如abcde/fghij n的表达式&#xff0c;其中a&#xff5e;j恰好为数字0&#xff5e;9的一个排列&#xff08;可以有前导0&a…