C++:4.模板

引入
C++是产生是用来解决C语言解决得不好或者解决不了的问题,比如:
- C语言中我们实现一个需要在堆申请空间的数据结构,比如顺序表,链表,栈和队列。在每次使用前需要手动初始化该数据结构,不用了要手动释放。每次使用都要重复枯燥地做一遍,特别麻烦,而且很容易忘记,所以在C++中就添加了构造函数和析构,对象创建自动初始化,对象销毁前自动清理资源。释放了人力
- C语言中,我们实现的数据结构里的数据,因为函数和变量是分开的,而函数和变量之间又没有强相关的关系,也就每办法区分自身函数的访问和其他函数的访问所以自身函数可以访问自己的变量,其他函数也可以访问,我的变量就谁都可以修改,数据就不安全,所以在C++中就引入了类和访问限定符,函数和变量放在一起,我可以随便访问,但是,对于类外面的函数,如果想要修改我的变量,因为我的成员默认是private的,所以其他函数修改不了我的变量,我想给你修改,我就将访问限定符改为public的。实现了封装,数据就更安全。
3.最后就是template,也就是模板该出场的时候了。如果是在C语言中,相同的功能,代码相同,只是参数不同,我们就要写多份不同的代码。这个问题有没有什么方法解决呢,C++中就引入了template,相同的代码,如果只是参数不同,我们就只需要写一次,编译器会根据我们指定的参数类型,或者传入参数的类型自动推导出相应的类或者函数。
前言
hi,我是firdawn,这章我们将介绍模板的概念和使用规则。下面是本章的思维导图,那么让我们开始学习模板吧!

概念
模板是一个模具,编译器在预处理阶段会通过我们的模板,根据我们指定的或者编译器自动识别的类型,通过模具自动生成对应的类或者函数。
模板主要分为两类:
- 函数模板
- 类模板
函数模板
概念
函数模板是函数的模板,编译器通过函数模板会生成对应的函数。
用法
template <class T>
void Swap(T& x,T& y)
示例
cpp
# include<iostream>
using namespace std;
int main()
{
//隐式实例化
int x_i=0,y_i=6;
Swap(x_i,y_i);
double x_dou=0.1,y_dou=6.1;
Swap(x_dou,y_dou);
//显式实例化
//这里y_dou会被隐式类型转换为int,传入形参y
Swap<int>(x_i,y_dou)
}
类模板
概念
类模板就是类的模板,编译器可以通过类模版在预处理阶段生成对应的类。
用法
template <class T>
class Stack
{
private:
T* _arr;
int _size;
int _capacity;
}
示例
cpp
//C++实现
template <class T>
class vector
{
public:
vector();
~vector();
void PushBack(T val);
void PopBack();
T& operator[](const int& i)const;
int Size();
bool IsEmpty();
private:
T* _arr;
int _size;
int _capacity;
};
template <class T>
vector<T>::vector()
:_arr(nullptr)
,_size(0)
,_capacity(0)
{}
template <class T>
vector<T>::~vector()
{
delete[] _arr;
_arr = nullptr;
_size = _capacity = 0;
}
template <class T>
T& vector<T>::operator[](const int& i)const
{
assert(i >= 0 && i < _size);
return _arr[i];
}
template <class T>
void vector<T>::PushBack(T val)
{
//空间不够先扩容
if (_size == _capacity)
{
int newcapacity = _capacity == 0 ? 4 : _capacity * 2;
T* tmp = new T[newcapacity];
if (_size)
{
memcpy(tmp, _arr, sizeof(T) * _size);
}
delete[] _arr;
_arr = tmp;
_capacity = newcapacity;
}
_arr[_size++] = val;
}
template <class T>
void vector<T>::PopBack()
{
assert(_size > 0);
--_size;
}
template <class T>
int vector<T>::Size()
{
return _size;
}
template <class T>
bool vector<T>::IsEmpty()
{
return _size == 0;
}
//int main()
//{
// //C++中的顺序表
// vector<int> v1;
// v1.PushBack(1);
// v1.PushBack(2);
// v1.PushBack(3);
// v1.PushBack(4);
// v1.PushBack(5);
//
// for (int i = 0; i < v1.Size(); i++)
// {
// cout << v1[i] << " ";
// }
// cout << endl;
//
// for (int i = 0; i < v1.Size(); i++)
// {
// v1[i] *= 2;
// }
//
// for (int i = 0; i < v1.Size(); i++)
// {
// cout << v1[i] << " ";
// }
// cout << endl;
//
//
//
//
// return 0;
//}
