内存管理和模板

news2024/12/28 6:01:51

目录

定位new表达式

定位new使用的池化技术:

 ​编辑

malloc和free与new和delete的区别:

 内存泄漏:

模板

 显示实例化

两个不同参数的模板

 模板函数与函数:

 类模板

[]重载:


定位new表达式

class A
{
public:
	A(int a=0)
		:_a(a)
	{
		cout << "构造函数" << this << endl;
	}
	~A()
	{
			cout << "析构函数" << endl;
	}
private:
	int _a;
};

int main()
{
	A*p1 = new A;
	//A*p2 = new A[10];
	A*p3 = (A*)malloc(sizeof(A));
	if (p3 == nullptr)
	{
		perror("malloc fail");
		exit(-1);
	}
	new(p3)A(1);
	return 0;
}

使用场景:

已分配地址。

对对象完成初始化。

 

我们要完成释放:

 

也可以直接使用delete函数。

 

定位new使用的池化技术:

 

当我们要使用栈上的空间时,我们每一次使用堆空间都需要申请,我们可以建立一个内存池,该内存池有一部分内存,我们可以直接使用。

 对于这类可以不申请就可以使用的空间(内存池)

我们需要通过定位new来完成初始化

malloc和free与new和delete的区别:

 内存泄漏:

内存泄漏:指针丢了

指针丢了,我们就无法通过该指针释放对应空间,造成内存泄漏。

模板

#include<iostream>
using namespace std;
void Swap(int&a, int&b)
{
	int tmp = a;
	a = b;
	b - tmp;
}
void Swap(double&a, double&b)
{
	double tmp = a;
	a = b;
	b - tmp;
}
int main()
{
	int a = 1, b = 2;
	Swap(a, b);
	double x = 1.1, y = 2.2;
	Swap(x, y);
	return 0;
}

我们实现的两个函数功能相同,只是处理的变量类型不同,我们必须显示的定义出两个函数。

有没有办法可以只定义出一个函数实现以上操作呢?

#include<iostream>
using namespace std;
template <typename T>

//void Swap(int&a, int&b)
//{
//	int tmp = a;
//	a = b;
//	b - tmp;
//}
//void Swap(double&a, double&b)
//{
//	double tmp = a;
//	a = b;
//	b - tmp;
//}
void Swap(T&a, T&b)
{
	T tmp = a;
	a = b;
	b = tmp;
}
int main()
{
	int a = 1, b = 2;
	Swap(a, b);
	double x = 1.1, y = 2.2;
	Swap(x, y);
	return 0;
}

 

我们只用了一个函数就实现了多种类型的交换。

 Swap函数调用的是我们的函数模板吗?

答:并不是,我们定义的模板可以根据调用参数的类型来实例化出不同的重载函数:

 所以我们实例化函数并不是所有的函数都实例化,我们的实例化是对所调用函数的参数进行比对来进行实例化,我们调用几种不同类型的函数,就实例化几个函数。

实例化是编译器帮助完成的。

假如我们调用不同参数类型的交换函数,会怎么样呢?

int main()
{
	int a = 1, b = 2;
	Swap(a, b);
	double x = 1.1, y = 2.2;
	Swap(x, y);
	Swap(a, x);
	return 0;
}

这里并不能发生强制类型转换,类型转换发生在赋值或者传参之间,这里是实例化期间。

template<class T>
T Add(const T&left, const T&right)
{
	return left + right;
}
int main()
{
	int a = 1, b = 2;
	double c = 1.1, d = 2.2;
	/*cout << Add(a, b) << endl;
	cout << Add(c,d) << endl;*/
	cout << Add(a, c) << endl;
	return 0;
}

我们用const修饰了,传参时应该可以类型转换,为什么还会报错?

因为我们的模板函数的两个参数都是T,是相同的,所以我们无法调用使用两个不同参数的函数,我们可以多加一个模板参数。

 解决方法1:

template<class T>
//template<class T2>
T Add(const T&left, const T&right)
{
	return left + right;
}
int main()
{
	int a = 1, b = 2;
	double c = 1.1, d = 2.2;
	/*cout << Add(a, b) << endl;
	cout << Add(c,d) << endl;*/
	cout << Add((double)a, c) << endl;
	cout << Add(a, (int)c) << endl;
	return 0;
}

我们在模板实例化对象之前强制类型转化。

我们去掉const会报错:

我们把a强制类型转换为double进行传参,a本身并没有发生改变,改变的是临时变量,临时变量具有常性,不能用引用来接收。

 

 显示实例化

template<class T>
//template<class T2>
T Add(const T&left, const T&right)
{
	return left + right;
}
int main()
{
	int a = 1, b = 2;
	double c = 1.1, d = 2.2;
	/*cout << Add(a, b) << endl;
	cout << Add(c,d) << endl;*/
	/*cout << Add((double)a, c) << endl;
	cout << Add(a, (int)c) << endl;*/
	cout << Add<double>(a, c) << endl;
	cout << Add<int>(a, c) << endl;
	return 0;
}

两个不同参数的模板

template<class T1, class T2> 
//template<class T2>
T1 Add(const T1&left, const T2&right)
{
	return left + right;
}
int main()
{
	int a = 1, b = 2;
	double c = 1.1, d = 2.2;
	/*cout << Add(a, b) << endl;
	cout << Add(c,d) << endl;*/
	/*cout << Add((double)a, c) << endl;
	cout << Add(a, (int)c) << endl;*/
	cout << Add(a, c) << endl;
	cout << Add(a, c) << endl;
	return 0;
}

模板类参数类似于函数参数。

 模板函数与函数:

int Add(int a, int b)
{
	return a + b;
}
template<class T>

T Add(T a, T b)
{
	return a + b;
}
int main()
{
	int a = 1, b = 2;
	Add(1, 2);
	return 0;
}

同名的模板函数与函数可以同时存在。

两个函数都可以调用的前提下,我们首先调用已经显示实例化的普通函数,模板函数还需要实例化。

显示调用模板函数:

模板函数与同名函数可以同时存在的原因:

 

两个函数虽然同名,但是他们的函数名修饰规则不同。

 类模板

template<class T>
class Stack
{
public:
	Stack(int capacity = 4)
	{
		_a = (T*)malloc(sizeof(T)*capacity);
		if (_a == nullptr)
		{
			perror("malloc fail");
			exit(-1);
		}
		_top = 0;
		_capacity = capacity;
	}
	void Push(const T& x)
	{
		_a[_top++] = x;
	}
	~Stack()
	{
		free(_a);
		_a = nullptr;
		_top = _capacity = 0;
	}
private:
	T*_a;
	size_t _capacity;
	size_t _top;
};
int main()
{
	Stack<int> s1(10);
	s1.Push(2);
	Stack<double> s2(20);
	s2.Push(3.3);
	return 0;
}

注意这两个类并不是同一个类型。

因为他们所占空间大小不同,int占4个字节,double占8个字节。

[]重载:

#define N 10
template<class T>
class Array
{
public:
	T&operator[](size_t i)
	{
		return _a[i];
	}
private:
	T _a[N];
};
int main()
{
	Array <int> a1;
	a1[1] = 10;
	cout << a1[1] << endl;
	return 0;
}

 

并且我们知道,访问数组时容易出现越界而没有报错的情况,我们可以在这个重载函数中实现绝对检查:

 

我们也可以加上内联,提升效率。

inline T&operator[](size_t i)
	{
	/*	assert(i < 10);*/
		return _a[i];
	}

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

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

相关文章

基于yum制作kylin系统docker镜像

[rootlocalhost yeqiang]# yum install --installroot/home/yeqiang/kylin-docker/ yum 无法找到发布版本&#xff08;可用 --releasever 指定版本&#xff09; 警告&#xff1a;加载 /etc/yum.repos.d/ceph.repo 失败&#xff0c;跳过。 上次元数据过期检查&#xff1a;0:00:…

核货宝:服装店收银系统一般有哪些功能

服装店收银系统是店铺用于管理和处理销售交易的软件系统。它提供了一系列功能和工具&#xff0c;使服装店能高效地进行销售和收款操作。以下是服装店收银系统一般具备的功能&#xff1a; 1. 商品管理&#xff1a;包括商品的基本信息&#xff08;名称、价格、库存等&#xff09;…

睿趣科技:抖音开通蓝V怎么操作的

在抖音这个充满创意和活力的社交媒体平台上&#xff0c;蓝V认证成为了许多用户的梦想之一。蓝V认证不仅是身份的象征&#xff0c;还可以增加用户的影响力和可信度。但是&#xff0c;要在抖音上获得蓝V认证并不是一件容易的事情。下面&#xff0c;我们将介绍一些操作步骤&#x…

word怎么删除空白页?图文详解来了(3种方法)

word是最常用的文档编辑工具之一&#xff0c;但有时在编辑文档时&#xff0c;我们会遇到一个常见问题&#xff0c;那就是不小心插入了空白页。这些空白页可能会破坏文档的布局&#xff0c;使其看起来不专业。那word怎么删除空白页呢&#xff1f;幸运的是&#xff0c;word提供了…

【AD】【pcb】【布线经验】打孔的目的

打孔的目的 就像老师说的&#xff0c;把GND层比作是大海&#xff0c;当拉线引流的时候&#xff0c;需要流动一定的路径。如果直接打孔&#xff0c;可以省略掉这部分路径。 现在知道了为什么&#xff0c;看别人布的板子 铺铜的时候&#xff0c;是一大片 一大片的在布的 然而也…

阿里云通义千问14B模型开源!性能超越Llama2等同等尺寸模型

9月25日&#xff0c;阿里云开源通义千问140亿参数模型Qwen-14B及其对话模型Qwen-14B-Chat,免费可商用。Qwen-14B在多个权威评测中超越同等规模模型&#xff0c;部分指标甚至接近Llama2-70B。阿里云此前开源了70亿参数模型Qwen-7B等&#xff0c;一个多月下载量破100万&#xff0…

LeetCode 1173.即时食物配送

数据准备 drop table Delivery;Create table If Not Exists Delivery (delivery_id int, customer_id int, order_date date, customer_pref_delivery_date date); Truncate table Delivery; insert into Delivery (delivery_id, customer_id, order_date, customer_pref_deli…

设备自动化系统EAP在晶圆厂的关键作用

在现代晶圆厂中&#xff0c;设备自动化系统&#xff08;Equipment Automation Programming&#xff0c;EAP&#xff09;已经成为了不可或缺的关键要素。EAP系统不仅是生产自动化的重要组成部分&#xff0c;更是连接制造执行系统&#xff08;MES&#xff09;与设备之间的桥梁&am…

mysql-4:SQL的解析顺序

SQL语句的解析顺序 文章目录 SQL语句的解析顺序编写顺序与解析顺序解析顺序关键字FROMONOUTER JOINWHEREGROUP BYHAVINGSELECTDISTINCTORDER BYLIMIT 解析流程流程分析流程说明WHERE条件解析顺序 编写顺序与解析顺序 编写顺序 SELECT DISTINCT < select_list > FROM &l…

使用ALU,RAM,寄存器打造一个CPU

CPU简介 计算机的心脏是中央处理单元&#xff0c;简称“CPU” 。这篇文章就利用前几篇文章中提到过的ALU,RAM,寄存器组件做一个CPU。 CPU负责运行程序&#xff0c;程序是由一个个操作组成的&#xff0c;这些操作叫做指令&#xff0c;因为他们“指示”计算机要做什么. CPU能做什…

登录业务实现 - token登录鉴权

登录业务实现&#xff1a; 登录成功/失败实现 -> pinia管理用户数据及数据持久化 -> 不同登录状态的模板适配 -> 请求拦截器携带token&#xff08;登录鉴权&#xff09; -> 退出登录实现 -> token失效&#xff08;401响应拦截&#xff09; 1. 登录成…

超详细C语言实现——通讯录

目录 一、介绍 二、源代码 test.c: Contact.c: Contact.h: 代码运行结果&#xff1a; 三、开始实现 1.基本框架&#xff1a; 2.添加联系人&#xff1a; 3.显示联系人信息&#xff1a; 4.删除联系人信息&#xff1a; 5.查看指定联系人信息&#xff1a; 6.修改联系人…

多维时序 | MATLAB实现PSO-BP多变量时间序列预测(粒子群优化BP神经网络)

多维时序 | MATLAB实现PSO-BP多变量时间序列预测(粒子群优化BP神经网络) 目录 多维时序 | MATLAB实现PSO-BP多变量时间序列预测(粒子群优化BP神经网络)效果一览基本介绍程序设计参考资料 效果一览 基本介绍 1.Matlab实现PSO-BP粒子群优化BP神经网络多变量时间序列预测&#xff…

初学vue.js

准备Vue.js环境 ① 下载环境&#xff1a; javaScript语言的程序包&#xff1a;外部js文件 对于Vue来说&#xff0c;导入Vue的外部js文件就能够使用Vue框架了。 Vue框架的js文件获取: 官网提供的下载地址&#xff1a;https://cdn.jsdelivr.net/npm/vue/dist/vue.js ②导入环境…

Kotlin中使用Java数据类时引发的一个Bug

文章目录 基础复习&#xff1a;Kotlin语言中的对象比较背景问题出现解决方式方式一方式二 基础复习&#xff1a;Kotlin语言中的对象比较 比较对象的内容是否相等 ( 或者 equals )&#xff1a;Kotlin 中的操作符 和 equals效果相同 &#xff0c;都用于比较对象的内容是否相等,…

Wespeaker框架数据集准备(1)

1. 数据集准备(Data preparation) 进入wespeaker目录文件/home/username/wespeaker/examples/voxceleb/v2 对run.sh文件进行编辑 vim run.sh 可以看到run.sh里面的配置内容 #数据集下载&#xff0c;解压 stage1 #插入噪音&#xff0c;制作音频文件 stop_stage2 #数据集放置…

递归算法讲解,深度理解递归

首先最重要的就是要说明递归思想的作用&#xff0c;在后面学习的高级数据接口&#xff0c;树和图中&#xff0c;都需要用到递归&#xff0c;即深度优先搜索&#xff0c;如果递归掌握的不好&#xff0c;后面的数据结构将举步为艰。 加油 首先看下如何下面两个方法有什么区别&a…

基于Java+SpringBoot+Vue3+Uniapp前后端分离考试学习一体机设计与实现2.0版本(视频讲解,已发布上线)

博主介绍&#xff1a;✌全网粉丝4W&#xff0c;全栈开发工程师&#xff0c;从事多年软件开发&#xff0c;在大厂呆过。持有软件中级、六级等证书。可提供微服务项目搭建与毕业项目实战&#xff0c;博主也曾写过优秀论文&#xff0c;查重率极低&#xff0c;在这方面有丰富的经验…

Allegro如何将丝印文字Change到任意层面操作指导

Allegro如何将丝印文字Change到任意层面操作指导 在用Allegro进行PCB设计的时候,有时需要将丝印文字change到其它层面,如下图 可以看到丝印文字是属于REFDES这个Class的 如果需要把丝印文字change层面,只支持REFDES中以下的层面中来change

【深入浅出设计模式--命令模式】

深入浅出设计模式--命令模式 一、背景二、问题三、解决方案四、试用场景总结五、后记 一、背景 命令模式是一种行为设计模式&#xff0c;它可以将用户的命令请求转化为一个包含有相关参数信息的对象&#xff0c;命令的发送者不需要知道接收者是如何处理这条命令&#xff0c;多个…