新闻详情

新闻详情

首页 / 资讯中心 / 详情

C++内存管理 + 模板

发布时间:2026/9/30 10:40:56来源:尧图网络
C++内存管理 + 模板
༺ 个人主页 · 纪念229 ༻我的博客主页༒专栏目录《数据结构》༒༒专栏目录《算法》༒༒专栏目录《C》༒༒专栏目录《MySQL数据库》༒༒专栏目录《前端开发》༒༒其它有趣的计算机知识༒༺世上本没有路走的人多了自然就有了༻本篇文章讲述的是C内存管理和模板的内容希望对你有所帮助本篇文章主要以代码的形式讲解文章目录1.内存管理2.模板1.内存管理#includeiostreamusing namespace std;//class A//{//public:// A(int a 0)// :_a(a)// {// cout A(int a 0) endl;// }// ~A()// {// cout ~A() endl;// }//private:// int _a;//};////int main()//{// A* p5 (A*)malloc(sizeof(A) * 10);// free(p5);//// A* p6 new A[10];// delete[] p6;// return 0;//}这里讲的是malloc与new申请空间和销毁的方式之前文章解释过这里就不赘述了//#define _DEBUG_BIT//void func()//{// for (size_t i 0; i 100000; i)// {// //int* p1 (int*)malloc(sizeof(int) * 1024 * 1024); //4M// //if (p1)// //{// // cout i - p1 endl;// //}// //else// //{// // break;// //}//#ifdef _DEBUG_BIT// if (i 493)// {// int x 0;// }//#endif// int* p1 new int[1024 * 1024];//4M// //申请失败自动抛出异常// cout i - p1 endl;////这个#define XX//////// #ifdef XX //如果#define XX代码里的东西才能执行//// 代码//// #endif//// 代码里写if 条件是 i 397////目的是在里面打一个断点当我们////循环到i 397 的时候再看////用不着我们一个个点到第397次循环////不想用这段代码将#define XX注释即可////#ifdef//// 代码 不再编译//// #endif////////// }//}////int main()//{// //try/catch就是给抛异常代码的// //的接盘机制让程序死的体面//////// //try 和 catch//// 结构//// try//// {//// //可能出错的代码放这里//// }//// catch(异常类型 变量名)//// {//// //出错后处理的代码//// }////如果代码里的new失败抛异常////catch就会接收异常////并打出错在哪里//// 异常有多种举列catch()//// 这些都在小括号里//// const bad_alloc e 内存不足//// const out_of_range e 越界//// const (std::)exception e//// 继承自std::expection的标准异常//// 如std::runtime_error std::out_of_range//// 这些异常类型都在std域内//////// const ... 包含所有异常// try// {// func();// }// catch (const exception e)// {// //这里为啥不用exception e// // 原因:exception是类不加const 会触发拷贝构造// cout e.what() endl;// //代码里的what()函数是exception类的一个成员函数// //返回有错误信息的字符串// //错误信息字符串的内容由抛异常的地方决定// //// }// return 0;//}先解释main函数里的try{//代码可能出现的代码}catch(异常类型 变量名){//出错后处理的代码}一般是new申请空间失败抛异常代码里的new失败抛异常catch就会接收异常并打出异常在代码那一行异常可以是任何类型(最常见的是new抛异常类型expection)举列catch()这些都在小括号里返回意思const bad_alloc e 内存不足const out_of_range e 越界const (std::)expection的标准异常如std::runtime_error std::out_of_range(这些异常类型都在std域内)…(表示所有异常)try// {// func();// }// catch (const exception e)// {// //这里为啥不用exception e// // 原因:exception是类不加const 会触发拷贝构造// cout e.what() endl;// //代码里的what()函数是exception类的一个成员函数// //返回有错误信息的字符串// //错误信息字符串的内容由抛异常的地方决定// //// }这里为啥不用expection e 我们知道expection 这是一个类我们在形参这样写会调用拷贝构造这里what()是什么首先我们知道e是expection类类型what是该类中的成员函数作用是打印抛异常的那一行代码接下来讲解预处理指令//#define _DEBUG_BIT 这个的意思就是定义_DEBUG_BIT这个东西下面两个预处理指令配套//#ifdef _DEBUG_BIT//#endif指令后面的东西就是个名字//#ifdef _DEBUG_BITif(i493)// {// int x 0;// }//#endif我主要讲这个如果定义了_DEBUG_BIT (#ifdef _DEBUG_BIT )里面的函数就可以使用把它注释了或者没定义里面的函数就不可以用这段代码这要用于调试我们给条件语句里打一个断点等循环到这就进入条件语句代码调式停止如果不用这个代码我们想看第493次循环我们要点多少时间浪费时间//double Divide(int a, int b)//{// //当b 0时抛出异常// if (b 0)// {// string s(Divide by zero condition!);// throw s;// }// else// {// return ((double)a / (double)b);// }// cout __FUNCTION__ : __LINE__ 行执行// //这两个是宏定义标识符// //__FUNCTION__ 展开成当前行号// //__LINE__展开成当前函数名// //之前写的FUNCTION LINE// //没在左右两边各加两个下划线// //由于没有不会当成字符串// //不加的字符串会当成名字去全局里找找不到就报未定义////// endl;//}////void main()//{// int len, time;// cin len time;// try// {// cout Divide(len, time) endl;// }// catch (const string errmsg)// {// cout errmsg endl;// }这里的catch里放的string异常代码里也是throw s一般用new抛异常就会自动throw其它类型抛异常一般就是要手动throw抛异常doubleDivide(inta,intb)//{// //当b 0时抛出异常// if (b 0)// {// string s(Divide by zero condition!);// throw s;// }// else// {// return ((double)a / (double)b);// }// cout __FUNCTION__ : __LINE__ 行执行// //这两个是宏定义标识符// //__FUNCTION__ 展开成当前行号// //__LINE__展开成当前函数名// //之前写的FUNCTION LINE// //没在左右两边各加两个下划线// //由于没有不会当成字符串// //不加的字符串会当成名字去全局里找找不到就报未定义////// endl;//}这里就是防止分母为0就弄一个string类型的 sthow 就是抛异常catch就接收并打印异常原因cout __FUNCTION__ : __LINE__ 行执行这两个是宏定义标识符这两个字符串左右两边都必须各有两个下划线否则就是名字会从文件里找函数名、类名等找不到就报未定义用 就打印的是字符串作用FUNCTION展开当前行号LINE展开当前函数名//typedef int STDataType;//class Stack//{//public:// Stack(int n 4)// {// cout Stack(int n 4) endl;//// _a (STDataType*)malloc(sizeof(STDataType) * n);// if (_a nullptr)// {// perror(malloc申请空间失败);// //perror头文件#inlcudecstdio// return;// }// _capacity n;// _top 0;// }// ~Stack()// {// cout ~Stack() endl;// free(_a);// _a nullptr;// _capacity _top 0;// }//private:// STDataType* _a;// size_t _capacity;// size_t _top;//};////////int main()//{// //Stack* p1 new Stack[10];// //delete p1;//// int* p2 new int(1);// //free(p2);// delete p2;// return 0;//}这里就是通过new申请空间给空间的元素初始化然后销毁空间new比malloc多了一个自动调用构造函数delete 比free多了一个析构函数这里的delete p1;因该改为delete[] p1因为这样只会调用一次析构函数这样写在VS会报错VS较严格放在题目不会报错//class A//{//public:// A(int a 0)// :_a(a)// {// cout A(int a 0) endl;// }//// ~A()// {// cout ~A() this endl;// }// private:// int _a;//};//int main()//{// /*A* p1 new A[10];// delete[] p1;*///// A* p1 (A*)malloc(sizeof(A));// //malloc不能调用构造//// //不能这样显示调用构造// //p1-A(1);//// //要这样// new (p1)A(1);////这里的A(1)不是默认对象// //这个就是在p1内存中调用构造函数// //// // new A(1)// // 这个是申请一个空间在调用构造// //// // new (p1)A(1);// // 这个是直接在p1地址上调用构造函数// ////////// //可以析构// //p1-~A();//// free(p1);// return 0;//}malloc的对象不能自动调用构造函数可以调用析构函数要手动调用p1-~A();malloc的对象调用构造函数要调用new (p1)A(1);意思是调用构造函数传入实参1这个对象在p1这个地址中构造最后返回指针new (p1)A(1);new A(1);区别一个已有地址把构造对象放在内存一个向空间申请之后调用构造函数2.模板C模板分为函数模板类模板作用简化代码减少逻辑重复性代码我们来看看函数重载与函数模板//void Swap(int left, int right)//{// int temp left;// left right;// right temp;//}////void Swap(double left, double right)//{// double temp left;// left right;// right temp;//}////void Swap(char left, char right)//{// char temp left;// left right;// right temp;//}//函数模板//泛型编程//针对任意类型的对象交换////函数模板内容与普通函数相同时// 函数模板一般写在头文件//相同时优先用普通函数//结构//templatetypename/class 类型名// 一般用typename// void 函数名(类型名 对象名)// {// 内容//// }//templatetypename T////template不要头文件C自带//void Swap(T left, T right)//{// T temp left;// left right;// right temp;//}////int main()//{// int i 0, j 1;// double x 1.1, y 2.2;// Swap(i, j);// Swap(x, y);// return 0;//}函数重载就不赘述了就是写了交换函数函数模板结构templatetypename/class 类型名templateC自带无头文件typename/class都可以用以交换函数为例//templatetypename T////template不要头文件C自带//void Swap(T left, T right)//{// T temp left;// left right;// right temp;//}可以传任何内置类型进行交换//templateclass T//T Add(const T left, const T right)//{// return left right;//}////templateclass T1, class T2//void func(const T1 left, const T2 right)//{ }////int main()//{// int a1 10, a2 20;// double d1 10.1, d2 20.1;// //隐式实例化(实参类型推演模板参数)// cout Add(a1, a2) endl;// cout Add(d1, d2) endl;//// cout Add(a1, (int)d2) endl;// cout Add((double)a1, d2) endl;//// //显示实例化 显示指定模板参数// cout Addint(a1, d2) endl;// cout Adddouble(a1, d2) endl;// cout Addint(d1, d2) endl;// return 0;//}这里讲一下调用时如果实参类型不同或者想改变实参类型要用隐式实例化或显示实例化// //显示实例化 显示指定模板参数// cout Addint(a1, d2) endl;// cout Adddouble(a1, d2) endl;// cout Addint(d1, d2) endl;显示实例化Add(a1, d2)就是在函数名与小括号之间加个里面就是想要转换的类型隐式实例化Add(a1, (int)d2就是直接将实参隐式类型转换//专门处理int的加法函数//int Add(int left, int right)//{// return left right;////}////////通用加法函数//templateclass T////Add函数返回值是int 不是void//int Add(const T left, const T right)//{// return left right 10;//}//////int main()//{// int a1 10, a2 20;// double d1 10.1, d2 20.1;// //隐式实例化(实参类型推演模板参数)// cout Add(a1, a2) endl;// //普通函数和函数模板会进行重载协议// //若是匹配度一样的话优先用普通函数// cout Add(d1, d2) endl;// cout Addint(a1, a2);// //在匹配度相同的情况下用的(匹配度指的是比较返回值、函数名、形参)// //显示实例调用的是函数模板// return 0;//}这里讲个函数的匹配度返回类型 函数名 形参 相同就是完全匹配当函数重载和函数模板中有完全匹配的函数就会触发重载协议优先调用普通函数函数重载函数内容有差异无妨类模板//typedef double DateType;//////namespace bit//{// class stack// {// private:// DateType* _a;// int _top;// int _capacity;// };//}////int main()//{// bit::stack st1;//int// bit::stack st2;//double//// return 0;//}namespace bit{//类模板(用法与类函数差不多)templateclass Tclass stack{public://这里要加public://否则调用不了构造函数stack(intn4):_a(new T[n]),_top(0),_capacity(n){coutstack(int n 4)endl;}voidpush(constTx){//..扩容_a[_top]x;_top;}~stack(){//new申请了空间最后要销毁delete[]_a;_anullptr;_top0;_capacity0;cout~stack()endl;}private:T*_a;int_top;int_capacity;};}intmain(){try{//显示实例化bit::stackintst1;//类模板和函数模板都可以用显示实例化和隐式实例化bit::stackdoublest2;//对象通过空间构造成功后//对象就不用通过空间调用空间里的函数st1.push(1);st1.push(2);st1.push(3);st2.push(1.1);st2.push(2.2);st2.push(3.3);}catch(constexceptione){coute.what()endl;}return0;}类模板和函数模板差不多这里就不赘述了有了类模板我们想有什么类型的栈就用什么类型等…文章到此就告一段落希望对你有所帮助感谢观看
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

水稻虫害检测数据集:VOC+YOLO双格式5212张6类真实田间图像 2026/9/30 11:14:30

水稻虫害检测数据集:VOC+YOLO双格式5212张6类真实田间图像

简介:本资源为面向农业AI研发者与计算机视觉初学者的水稻虫害检测专用图像数据集,聚焦解决农作物病虫害智能识别中的高质量标注数据匮乏问题。数据集包含5212张高分辨率水稻田间害虫实拍JPG图像,全部配备Pascal VOC格式XML标注文件与YOLO格式…

阅读更多 →
屏幕添加与多屏设置完全指南:从分辨率和刷新率到护眼与排查 2026/9/30 11:14:30

屏幕添加与多屏设置完全指南:从分辨率和刷新率到护眼与排查

提到“添加屏幕”,很多人的第一反应是“插上线就能用”。但真正操作过你会发现,事情远没有那么简单——分辨率不对、刷新率跑不满、颜色发灰、窗口拖不过去、甚至干脆黑屏无信号,随便一个都能让人折腾半小时。这篇文章就是一次系统性的总结&a…

阅读更多 →
华为云Stack架构解析:从私有云部署到运维实战 2026/9/30 11:13:41

华为云Stack架构解析:从私有云部署到运维实战

说到华为云,很多人脑子里弹出来的第一幅画面,是官网首页那些按秒计费的弹性云主机的公有云产品。但华为云其实还有一条非常重要的产品线,专门面向政企客户,解决"数据不能出机房"但又想用云的问题——这就是华为HuaweiCl…

阅读更多 →
AI生成代码安全防线:用Harness Engineering治理Codex风险 2026/9/30 11:13:40

AI生成代码安全防线:用Harness Engineering治理Codex风险

1. Harness Engineering 遇上 Codex:一场绕不开的“代码新浪潮”防御战 过去两年,AI 生成代码从“玩具”变成了“主力”,我身边很多团队已经习惯把 OpenAI Codex、GitHub Copilot 这类工具直接接进 IDE 和 CI 流水线。Codex 这类工具能在几十…

阅读更多 →
SpringBoot+Vue+MySQL党员教育管理系统平台毕业设计实战 2026/9/30 11:13:33

SpringBoot+Vue+MySQL党员教育管理系统平台毕业设计实战

1. 这个毕业设计题目为什么值得做:先看清楚它到底是个什么系统 上半年我在后台收到大量私信,内容高度一致——"学长,SpringBootVueMySQL做的党员教育和管理系统平台,源码加数据库加论文加部署文档那一套,到底怎么…

阅读更多 →
从 Citation 到 Callability:GPT-6 降价、百万上下文与 AI 爬虫五万倍下的 GEO 技术应对 2026/9/30 11:13:26

从 Citation 到 Callability:GPT-6 降价、百万上下文与 AI 爬虫五万倍下的 GEO 技术应对

本文不是营销稿,是一次技术向的判断梳理。 2026-09-22 ~ 09-28 这一周,五件事叠加,让我认为 GEO(生成式引擎优化)的工程目标应该从「让 AI 引用(Citation)」升级为「让 AI 可调用(Ca…

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞 ✉