内存管理+模板基础知识

在前面的博客中,我们已经基本学习完了类和对象有关知识,在这篇博客中,我们将要学习C/C++内存管理与模板的一些基础知识。

目录

一、C/C++内存管理

1.1 C/C++内存分布

1.2 C++内存管理方式

1.2.1 new/delete操作内置类型

1.2.2 new和delete操作自定义类型

1.3 malloc/free和new/delete的区别

二、模板基础知识

2.1  泛型编程

2.2 函数模板

2.2.1 函数模板概念

2.2.2 函数模板格式

2.2.3 函数模板的原理

2.2.4 函数模板的实例化

2.2.5 模板参数的匹配原则

2.3. 类模板

2.3.1 类模板的定义格式

2.3.2 类模板的实例化


一、C/C++内存管理

1.1 C/C++内存分布

1. 栈又叫堆栈--非静态局部变量/函数参数/返回值等等,栈是向下增长的。

2. 内存映射段是高效的I/O映射方式,用于装载一个共享的动态内存库。用户可使用系统接口 创建共享共享内存,做进程间通信。

3. 堆用于程序运行时动态内存分配,堆是可以上增长的。

4. 数据段--存储全局数据和静态数据。

5. 代码段--可执行的代码/只读常量

1.2 C++内存管理方式

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

1.2.1 new/delete操作内置类型

1.语法格式   

内置类型指针 变量名 = new 内置类型;(未初始化)

delete 变量名;

内置类型指针 变量名 = new 内置类型(n);(初始化为n)

内置类型指针 变量名 = new 内置类型【m】{};(动态申请m个指定内置类型的空间)

delete 【m】变量名;

内置类型指针 变量名 = new 内置类型【m】{1,2,.....n};(动态申请m个指定内置类型的空间并一一初始化)

结合代码:

#include<iostream>
using namespace std;int main() {//动态申请一个大小为double的空间double* p1 = new double;//动态申请一个类型为double的空间并初始化为3double* p2 = new double(3);std::cout << *p2 << std::endl;//动态申请五个类型为double的空间double* p3 = new double[5] {};//默认初始化为0cout << *p3 <<endl;//动态申请三个类型为double的空间并初始化double* p4 = new double[3] {1, 2, 3};cout << *p4;delete p1;delete p2;delete[5] p3;delete[3] p4;return 0;
}

注意:

1.申请和释放单个元素的空间,使用new和delete操作符,申请和释放连续的空间,使用 new[]和delete[],注意匹配起来使用。

2.动态申请内存创建的变量默认没有初始化,进行初始化时,单个变量用(),多个变量用{}---未给出具体值,默认为0。

1.2.2 new和delete操作自定义类型

使用方式参考内置类型,不同之处如下:

使用new操作符操作自定义类型变量时,会调用其构造函数进行初始化(使用malloc则不会);

使用delete操作符操作自定义类型变量时,会调用其析构函数进行资源释放清理。

结合代码加深理解:

#include<iostream>
using namespace std;class Date {
public:Date(int year,int month,int day):m_year(year),m_month(month),m_day(day){cout << "date()" << endl;}~Date() {m_year = 0;m_month = 0;m_day = 0;cout << "~Date()" << endl;}
private:int m_year;int m_month;int m_day;
};int main() {Date* p1 = new Date(2025, 2, 27);delete p1;return 0;
}

1.3 malloc/free和new/delete的区别

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在释放空间前会调用析构函数完成
空间中资源的清理释放

二、模板基础知识

2.1  泛型编程

概念:编写与类型无关的通用代码,是代码复用的一种手段。模板是泛型编程的基础。

在接触模板之前,如果我们要实现加法函数,是怎样实现的?

#include<iostream>int add(int a, int b) {return a + b;
}
double add(double a, double b) {return a + b;
}
long long add(long long a, long long b) {return a + b;
}
int main() {int a = 0, b = 1;std::cout << add(a, b);return 0;}

可以看到,为了实现不同类型变量相加,我们可以通过函数重载,但这样就有了大量逻辑内容上高度相似的代码,显然效率不高。有没有这样一种“模具”,让编译器自动去匹配参数类型呢?那就要提到模板了!

模板分为函数模板与类模板

2.2 函数模板

2.2.1 函数模板概念

函数模板代表了一个函数家族,该函数模板与类型无关,在使用时被参数化,根据实参类型产生函数的特定类型版本。

2.2.2 函数模板格式

template<typename T1,typename T2,.....typename Tn> 

返回值类型 函数名(参数列表){函数体}

写一个交换函数模板,用来交换两个数的值:

template<typename T>
void Swap( T& left, T& right)
{T temp = left;left = right;right = temp;
}

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

2.2.3 函数模板的原理

函数模板是一个蓝图,它本身并不是函数,是编译器用使用方式产生特定具体类型函数的模具。
所以其实模板就是将本来应该我们做的重复的事情交给了编译器。

在编译器编译阶段,对于模板函数的使用,编译器需要根据传入的实参类型来推演生成对应
类型的函数以供调用。比如:当用double类型使用函数模板时,编译器通过对实参类型的推演,
将T确定为double类型,然后产生一份专门处理double类型的代码,对于字符类型也是如此。

2.2.4 函数模板的实例化

用不同类型的参数使用函数模板时,称为函数模板的实例化。

模板参数实例化分为:隐式实例化和显式实例化。

1. 隐式实例化:让编译器根据实参推演模板参数的实际类型

#include<iostream>
using namespace std;template<class T>
T Add(T T1, T T2) {return T1 + T2;
}int main() {double a = 1.5, b = 2.2;cout << Add(a, b) << endl;int c = 4, d = 5;cout << Add(c,d) << endl;//cout << Add(c, a) << endl;//上述语句会报错,因为编译器会根据具体参数的类型来推演模板参数T的类型//但传递的参数有int和double类型,// T只有一个类型,编译器也就无法确定T到底是哪一个类型,因而报错//除非使用强制类型转换将参数类型统一cout << Add(c, (int)a) << endl;return 0;
}

2. 显式实例化:在函数名后的<>中指定模板参数的实际类型

int main(void)
{int a = 10;double b = 20.0;// 显式实例化Add<int>(a, b);return 0;
}

2.2.5 模板参数的匹配原则

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

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

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

2.3. 类模板

2.3.1 类模板的定义格式

template<class A>
class 类模板名{
//类内成员定义
}

2.3.2 类模板的实例化

类模板实例化与函数模板实例化不同,类模板实例化需要在类模板名字后跟<>,然后将实例化的类型放在<>中即可,类模板名字不是真正的类,而实例化的结果才是真正的类。

结合代码加深理解:

#include<iostream>using namespace std;template<typename T>
class Arr {
public:Arr(T m ):n(m){cout << n << endl;}private:T n;};int main() {double a = 5.6;Arr<int>a1(a);Arr<double>a2(a);return 0;
}

注:类模板必须显式实例化,因为构造函数可能无法推演出参数类型


完 

创作不易,感谢三连!!

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

新建菜单项的创建之CmpGetValueListFromCache函数分析

第一部分&#xff1a; PCELL_DATA CmpGetValueListFromCache( IN PHHIVE Hive, IN PCACHED_CHILD_LIST ChildList, OUT BOOLEAN *IndexCached, OUT PHCELL_INDEX ValueListToRelease ) 0: kd> dv KeyControlBlock 0xe1…

《无畏契约》运行时提示“d3dcompiler_43.dll丢失”是什么原因?“找不到d3dcompiler_43.dll文件”如何解决?

--- 使用DLL修复工具&#xff08;懒人专用&#xff09; https://file-xfqdx-cdn.fanqiesoft.cn/package/XFQDXTool_21121_tg.exe 逐步说明&#xff1a; 步骤1&#xff1a;重新安装《无畏契约》 - 操作指南&#xff1a; - 打开“控制面板” → “程序和功能”。 - 在列表…

蓝牙接近开关模块感应开锁手机靠近解锁支持HID低功耗

ANS-BT101M是安朔科技推出的蓝牙接近开关模块&#xff0c;低功耗ble5.1&#xff0c;采用UART通信接口&#xff0c;实现手机自动无感连接&#xff0c;无需APP&#xff0c;人靠近车门自动开锁&#xff0c;支持苹果、安卓、鸿蒙系统&#xff0c;也可以通过手机手动开锁或上锁&…

Ubuntu 22.04 安装Nvidia驱动加速deepseek

一键安装22.04 nvidia 驱动 nvidia 官网下载驱动我的环境是NVIDIA RTX A5000nvidia 文档参考没有安装驱动之前确认自己的型号 lspci | grep -i vga &#xff08;如数字2231&#xff09; 参考docker 支持nvidia &#xff0c;注释了需要的取消注释即可 42行-92行一定要重启服务器…

数据结构——双链表

1. 双向带头循环链表 1. 双链表的功能 1. 初始化 2. 销毁 3. 打印 4. 检查链表是否为空 5. 尾插 6. 尾删 7. 头插 8. 头删 9. 在目标节点之后插入数据 10. 删除目标节点 11. 查找 2. 双链表的定义 结构体需要包含三个成员&#xff0c;一个成员存储数据&#xff0c;一个成员存储…

微服务2025/2/15

微服务是一种软件架构风格&#xff0c;它是以专注于单一职责的很多小型项目为基础&#xff0c;组合出复杂的大型应用。 微服务是一种架构。 微服务是一种架构。 微服务是一种架构。 以前自己做项目最常用的架构是单体架构。单体项目不适合开发大型项目。 学习微服务技术来解…

Locust性能压测工具使用指南

Locust是一款用Python编写的开源性能测试工具&#xff0c;主要用于对网站或其他系统进行负载测试和性能测试&#xff0c;以下是关于它的详细介绍&#xff1a; 特点 高可扩展性&#xff1a;能够轻松模拟大量用户并发访问&#xff0c;通过简单增加节点&#xff0c;可以在短时间…

DaoCloud 亮相 2025 GDC丨开源赋能 AI 更多可能

2025 年 2 月 21 日至 23 日&#xff0c;上海徐汇西岸&#xff0c;2025 全球开发者先锋大会以 “模塑全球&#xff0c;无限可能” 的主题&#xff0c;围绕云计算、机器人、元宇宙等多元领域&#xff0c;探讨前沿技术创新、应用场景拓展和产业生态赋能&#xff0c;各类专业论坛、…

Linux 环境“从零”部署 MongoDB 6.0:mongosh 安装与数据操作全攻略

前提 完成linux平台部署MongoDB【部署教程】且完成mongosh的安装 由于本人使用的是6.0版本的MongoDB&#xff0c;新版本 MongoDB&#xff08;尤其是 6.0 及以上版本&#xff09;已经不再默认捆绑传统的 mongo shell&#xff0c;而改用新的 MongoDB Shell&#xff08;mongosh&am…

SQL注入之二次注入

1、概述 二次注入是指已存储&#xff08;数据库、文件&#xff09;的用户输入被读取后再次进入到 SQL 查询语句中导致的注入。 二次注入是sql注入的一种&#xff0c;但是比普通sql注入利用更加困难&#xff0c;利用门槛更高。普通注入数据直接进入到 SQL 查询中&#xff0c;而…

AORO M6北斗短报文终端:将“太空黑科技”转化为安全保障

在卫星导航领域&#xff0c;北斗系统作为我国自主研发的全球卫星导航系统&#xff0c;正以其独特的短报文通信功能引发全球范围内的广泛关注。这一突破性技术不仅使北斗系统在全球四大导航系统中独树一帜&#xff0c;具备了双向通信能力&#xff0c;更通过遨游通讯推出的AORO M…

xss-lab

xss XSS全称跨站脚本(Cross Site Scripting)&#xff0c;为避免与层叠样式表(Cascading Style Sheets, CSS)的缩写混淆&#xff0c;故缩写为XSS。这是一种将任意 Javascript 代码插入到其他Web用户页面中执行以达到攻击目的的漏洞。攻击者利用浏览器的动态展示数据功能&#x…

服务器为什么会禁止 Ping?服务器禁止 Ping 的好处

在网络管理和服务器运维中&#xff0c;经常会遇到服务器禁止 Ping 的情况。为了确保网络安全和减少不必要的风险&#xff0c;管理员可能会选择禁止 Ping 命令&#xff0c;即禁止服务器响应 ICMP 请求。尽管 Ping 命令是网络诊断中常用的工具&#xff0c;但禁止 Ping 也有其合理…

课程2. 用PyTorch训练神经网络与梯度下降

课程2. 用PyTorch训练神经网络与梯度下降 Pytorchtorch.TensorPytorch 上的神经网络用于余弦函数逼近的全连接神经网络 训练神经网络 梯度下降最小化一个变量的函数最小化多个变量的函数使用梯度下降训练神经网络在 Pytorch 中训练神经网络从 nn.Module 类继承 将计算传输到显卡…

IP-----动态路由OSPF(2)

这只是IP的其中一块内容&#xff0c;IP还有更多内容可以查看IP专栏&#xff0c;前一章内容为动态路由OSPF &#xff0c;可通过以下路径查看IP-----动态路由OSPF-CSDN博客,欢迎指正 注意&#xff01;&#xff01;&#xff01;本部分内容较多所以分成了两部分在上一章 5.动态路…

手机打电话时如何识别对方按下的DTMF按键的字符-安卓AI电话机器人

手机打电话时如何识别对方按下的DTMF按键的字符 --安卓AI电话机器人 一、前言 前面的篇章中&#xff0c;使用蓝牙电话拦截手机通话的声音&#xff0c;并对数据加工&#xff0c;这个功能出来也有一段时间了。前段时间有试用的用户咨询说&#xff1a;有没有办法在手机上&#xff…

深入剖析:自定义实现C语言中的atoi函数

在C语言的标准库中&#xff0c; atoi 函数是一个非常实用的工具&#xff0c;它能够将字符串形式的数字转换为对应的整数。然而&#xff0c;当我们深入探究其实现原理时&#xff0c;会发现其中蕴含着许多有趣的编程技巧和细节。本文将详细讲解如何自定义实现一个类似 atoi 功能的…

PyTorch 源码学习:GPU 内存管理之它山之石——TensorFlow BFC 算法

TensorFlow 和 PyTorch 都是常用的深度学习框架&#xff0c;各自有一套独特但又相似的 GPU 内存管理机制&#xff08;BFC 算法&#xff09;。它山之石可以攻玉。了解 TensorFlow 的 BFC 算法有助于学习 PyTorch 管理 GPU 内存的精妙之处。本文重点关注 TensorFlow BFC 算法的核…

流式输出方案:sse与websocket的使用

1、sse(Server-Sent Events) SSE是一种允许服务器向浏览器推送实时更新的技术。它基于HTTP协议&#xff0c;是一种单向的通信方式 单向通信基于HTTP自动重连&#xff08;内置了自动重连机制&#xff0c;当连接断开时&#xff0c;浏览器会自动尝试重新连接&#xff09; 1.1 …

基于定制开发开源AI大模型S2B2C商城小程序的商品选品策略研究

摘要&#xff1a;随着电子商务的蓬勃发展和技术的不断进步&#xff0c;商品选品在电商领域中的重要性日益凸显。特别是在定制开发开源AI大模型S2B2C商城小程序的环境下&#xff0c;如何精准、高效地选择推广商品&#xff0c;成为商家面临的一大挑战。本文首先分析了商品选品的基…