这篇文章给大家介绍一下c嘎嘎内存管理和模板,那么我们直接进入正题
c/c++的程序内存分布
这里的了解一下即可
new和delete的定义和操作
格式:类型* 对象名 = new 类型;
数组(对象)定义格式:类型* 对象名 = new 类型[元素个数];
那么下面的几个例子大家可以看一下
delete格式
delete 对象名;
数组的delete格式:delete [ ] 对象名;
operator new语法格式:
类型* 对象名 = (类型*)operator (sizeof(类型));
new、delete 与 malloc 、free的区别
malloc和free是函数,new和delete是操作符
new/delete对于【自定义类型】除了开空间 还会调用构造函数和析构函数
malloc申请空间后不会初始化,而new申请了空间后会初始化
malloc申请空间时需要手动计算空间大小并传递,而new只需要在它的后面跟上类型即可,如果需要的是多个对象,[]中指定对象个数即可
malloc的返回值为void*, 在使用时必须强转,new不需要,因为new后跟的是空间的类型
malloc申请空间失败时,返回的是NULL,因此使用时必须判空,new不需要,但是new需 要捕获异常
申请自定义类型对象时,malloc/free只会开辟空间,不会调用构造函数与析构函数,而new 在申请空间后会调用构造函数完成对象的初始化,delete在释放空间前会调用析构函数完成 空间中资源的清理释放
捕获异常
格式:try{
语句
}
catch(const exception& e)
{
cout << e.what << endl;//其中e.what就是发生的异常
}
C嘎嘎模板
函数模板
语法格式:
template<class/typename 类型>
类型 函数(参数)
{
语句;
}
eg.
template<class T>
void Swap(T& a, T&b)
{
T tmp = a;
a = b;
b = tmp;
}
函数模板的参数列表与函数参数列表的类比
template<class 类型1, class 类型2>
||||
返回类型 函数名(类型 变量名1,类型 变量名2)
泛型编程:编写与类型无关的通用代码,是代码复用的一种手段。模板是泛型编程的基础。
模板:函数模板、类模板
推到实例化和显示实例化
推导实例化:函数名(变量,(类型)变量);
显式实例化:函数名<类型>(变量,变量);
bug修复小tip:当编译器报出未能推导模板参数 ————> 显示实例化
模板参数的匹配原则
1.一个非模板函数可以和一个同名的函数模板同时存在,且该模板还可以被实例化为这个函数非模板函数
2. 对于非模板函数和同名函数模板,如果其他条件都相同,在调动时会优先调用非模板函数而 不会从该模板产生出一个实例。如果模板可以产生一个具有更好匹配的函数, 那么将选择模 板
3.模板函数不允许自动类型转换,但普通函数可以进行自动类型转换
类模板
语法格式:
template class 类模板名
{
// 类内成员定义
};
eg.
#include using namespace std;
// 类模版
template class Stack
{
public:
Stack(size_t capacity = 4)
{
_array = new T[capacity];
_capacity = capacity;
_size = 0;
}
void Push(const T& data);
private:
T* _array;
size_t _capacity;
size_t _size;
}; // 模版不建议声明和定义分离到两个文件.h 和.cpp会出现链接错误
template void Stack::Push(const T& data)
{
// 扩容 _array[_size] = data;
++_size;
}
int main()
{
Stack st1; // int
Stack st2; // double
return 0;
}
// Stack是类名,Stack才是类型
Stack st1; // int
Stack st2; // double
拓展部分
相信学到这里的同学,大家对栈的知识都是清楚的,那么这里我想要提醒大家的是在使用模板后,main函数中我们需要用上实例化,否则实例化对相处处会报错
那么本篇文章就先到这,我们下期再见