总结:为什么有这么多的区域?
1.不同的数据变量需要不同的空间去存放:
2.不同的数据对于程序有不同的公用!
C语言内存管理方式在C++中可以继续使用,但有些地方就无能为力,而且使用起来比较麻烦,因此C++又提出了自己的内存管理方式:通过new和delete操作符进行动态内存管理。
注意:
1.new和delete对应 :申请和释放单个元素空间 。
2.new 类型[] 和 delete[] 对应 :申请和释放多个元素空间。
3.对于上面的操作其实C语言中的开辟动态开辟也可以做的到那么为什么C++中要加入nwe和delete呢?
之前的类的delete都是去调用默认析构函数进行的空间释放因为类型比较简单不会涉及到深浅拷贝的问题,对于栈这个类就不一样了!
大致概念:
new和delete是用户进行动态内存申请和释放的操作符,
operator new 和operator delete是系统提供的全局函数,new在底层调用operator new全局函数来申请空间,delete在底层通过operator delete全局函数来释放空间。
通过日期类和反汇编观察函数执行过程:
1.nwe去调用operator new函数:
2.jmp 命令跳到operator new 全局函数:
3.调用ooperator new 函数进行开辟空间不初始化!
6.使用定义operator delete
1.operator delete 里面调用了函数:
2.本质使用了free函数进行空间释放:
new和delete malloc和free 没有区别的,可以不用考虑new和delete不对应的情况!因为自定义类型不需要考虑调用多少次析构函数这个问题!
2-1.对于自定义类型操作:
new和delete malloc和free 有区别的,需要考虑new和delete不对应的情况?
观察一下栈类空间开的大小?
解释开辟多个数据只需要在new的时候去写[n]不需要在delete的时候去写数值,并且对于自定义类型是这样的是因为自定义类型可以知道调用多少次析构函数释放空间。
为什么使用operatot new 进行封装呢?
因为malloc 开辟空间失败会返回空指针,operator new 开辟空间失败会抛出异常!
为什么使用operator delete 进行封装呢 ?
1.经过封装可以找到需要调用析构函数的次数并且多次调用析构函数对于自定义类型看多个空间的情况
2.对于单个空间只需要调用一次析构函数就可以了!
new
1.调用operator new 进行空间开辟:
2.调用构造函数进行空间的初始化:
delete
1.调用析构函数进行空间的内层释放:
2.调用operator delete 进行空间的外层释放:
补充:
1.operator new 是不可以显示调用的!
2.operator delete 是可以进行显示调用的!
用法+原理:
有没有一种方法可以创造一个模板去使用自定义类型去使用!
那能否告诉编译器一个模子,让编译器根据不同的类型利用该模子来生成代码呢?
1.使用关键字: template
2.放在函数定义的前面可以进行类型的控制了!
3.注意:typename是用来定义模板参数关键字,也可以使用class(切记:不能使用struct代替class)
4.函数模板是一个蓝图,它本身并不是函数,是编译器用使用方式产生特定具体类型函数的模具。所以其实模板就是将本来应该我们做的重复的事情交给了编译器
3.底层原理:
那么这个函数是如何调用的呢?
两个swap会去使用同一个swap函数吗?
通过反汇编去观察具体的情况!
通过观察我们会发现两个swap函数调用去call的函数的参数不同(通过模板和传参确定的),并且地址也不相同说明通过模板和参数的不同实例化了两个swap函数这个操作是编译器自己完成的。
用不同类型的参数使用函数模板时,称为函数模板的实例化。
模板参数实例化分为:隐式实例化和显式实例化。
如果存在两个都可以满足的函数编译器优先匹配程度更高的内容
不去实例化就会节省空间:
// 专门处理int的加法函数
int Add(int left, int right)
{
return left + right;
}
// 通用加法函数
template<class T>
T Add(T left, T right)
{
return left + right;
}
void text()
{
//优先调用处理int的函数不会去用模板进行实例化!
int a,b;
Add(a,b)
double c,d;
Add(c,d)
}
1.我们之前使用C语言实现的一个栈对于存贮数据类型的控制我们是使用typedef 进行类型的重命名去改变栈中的数据类型的方法!
2.这个方法其实不是很方便比如说我们有一个类需要两个类型数据内容的栈我们如果用之前的方法需要写两份相同的代码只有数据类型不相同。
3.解决:这个时候我们就可以使用类模板去解决这个问题:
4.注意:类的成员函数的定义和声明不可以分离!
vector 和 list的使用: