模板
模板参数
template<typename T>
T代表了一个模板类型(虚拟的)
template<typename T>
//tmplate<class T> 也可以
void Swap(T& left,T& right)
{
T tmp=left;
left=right;
right=tmp;
}
函数模板的实例化
template<class T>
T Add(const T& left,const T& right)
{
return left+right;
}
int main()
{
//编译器自动推演,隐式实例化
Add(1,2);
//Add(1.1,2);//报错 推演实例化(1个double类型 1个int类型)失败
Add((int)1.1,2);
Add(1.1,(double)2);
//显示实例化
Add<int>(1.1,2);
Add<double>(1.1,2);
return 0;
}
情况二
template<class T>
T* Func(int n)
{
T*a=new T[n];
return a;
}
int main()
{
//必须显示实例化才能调用
Func<A>(10);
reruen 0;
}
栈的部分实现(情况3)
template<typename T>
class Stack
{
public:
//初始化列表
Stack(size_t capacity=4)
:_a(nullptr)
,_capacity(0)
,_top(0)
{
if(capacity>0)
{
_a=new T[capacity];
_capacity=capacity;
_top=0;
}
}
~Stack()
{
delete[] _a;
_a=nullptr;
_capacity=0;
_top=0;
}
void Push(const T& x)
{
if(_top==_capacity)
{
size_t newCapacity=_capacity==0?4:_capacity*2;
//1.开新空间
//2.拷贝数据
//3.释放旧空间
T* tmp=new T[newCapacity];
if(_a)//_a有数据拷贝 memcpy给空指针报错
{
memcpy(tmp,_a,sizeof(T)*_top);
delete[] _a;
}
_a=tmp;
_capacity=newCapacity;
}
_a[_top]=x;
_top++;
}
void Pop()
{
assert(_a);
_top--;
}
bool Empty()
{
return _top==0;
}
const T& Top()//取栈顶数据
{
assert(_top>0)
return _a[_top-1];
}
private:
T* _a;
size_t _top;
size_t _capacity;
};
int main()
{
//类模板都要写成显示实例化
//虽然使用了一个类模板 但是
Stack<int> st1;
Stack<char> st2;
st1.Push(1);
st1.Push(2);
return 0;
}
扩容时不能使用relloc是因为不能初始化,因为是采用构造函数初始化的,只有new可以完成。
类模板不支持分离编译.声明和定义必须放在一个文件里面。
STL
标准模板库,是C++标准库的重要组成部分。
string类
string 动态增长char字符数组