1理解函数模板
#include<iostream>
using namespace std;//函数模板
template<typename T> //定义一个模板参数列表
//模板类型参数 typename/class
bool compare(T a, T b)
{cout << "template compare: " << endl;return a > b;
}template<>
bool compare(const char* a, const char* b)
{cout << "compare(char*)";return strcmp(a, b) > 0;
}//非模板函数
bool compare(const char* a, const char* b)
{cout << "normal compare: " << endl;return strcmp(a, b) > 0;
}
/*函数调用点,编译器用用户指定的类型,从原来的模板实例化一份函数代码出来*/
int main()
{compare<int>(10, 20);compare(20, 30); //推导出来是整形 模板实参法推演//compare(30, 4.5);b报错,找不到compare<int>(30, 3.4); //这样子可以但是被会警告//对于某些类型来说,依赖编译器默认实例化的模板代码,代码处理逻辑是有错误的compare("aaa", "bbb"); //不能a>b来处理//模板的特例化,不是编译器提供的,而是用户提供的实例化return 0;
}
//份文件的时候 直接告诉编译器模板指定类型的模板实例化
template bool compare<int>(int, int);
template bool compare<double>(double, double);
2、理解类模板
#include<iostream>
using namespace std;template<typename T, const int SIZE>
void sort(T* arr)
{for (int i = 0; i < SIZE - 1; i++){for (int j = 0; j < SIZE - 1 - i; j++){if (arr[j] > arr[j + 1]){int tmp = arr[j];arr[j] = arr[j + 1];arr[j + 1] = tmp;}}}
}
//类模板
int main()
{int arr[] = { 12,2,2,2,2,2 };const int size = sizeof(arr) / sizeof(arr[0]);sort<int, size>(arr);for (int val : arr){cout << val << " ";}cout << endl;
}#include<iostream>
using namespace std;
#include<time.h>
template<typename T> //模板+参数列表 = 类名称
class SeqStack
{
public://构造函数和析构函数不要加模板类型参数列表SeqStack(int size = 10):_stack(new T[size]),_top(0),_size(size){}~SeqStack(){delete[]_stack;_stack = nullptr;}SeqStack<T>(const SeqStack<T>& stack):_top(stack._top),_size(stack._size){_stack = new T[_size];//不要用memcopy进行拷贝for (int i = 0; i < _top; i++){_stack[i] = stack._stack[i];}}SeqStack<T>& operator = (const SeqStack<T>& stack){if (this == &stack)return *this;delete[] _stack;_top = stack._top;_size = stack._size;_stack = new T[_size];//不要用memcopy进行拷贝for (int i = 0; i < _top; i++){_stack[i] = stack._stack[i];}return *this;}void push(const T& val){if (full())expand();_stack[_top++] = val;}void pop(){if (empty()){return;}--_top;}T top() const{if ((empty()))throw "stack is empty()"; //抛出异常结束return _stack[_top - 1];}bool full()const{return _top == _size;}bool empty()const{return _top == 0;}
private:T* _stack;int _top;int _size;//顺序栈底层数void expand(){T* ptmp = new T[_size * 2];for (int i = 0; i < _top; i++){ptmp[i] = _stack[i];}delete[]_stack;_stack = ptmp;ptmp = nullptr;_size *= 2;}
};
int main()
{SeqStack<int>stack(4);for (int i = 0; i < 20; i++){stack.push(rand() % 100);}while (!stack.empty()){cout << stack.top() << " ";stack.pop();}cout << endl;SeqStack<int>stack1(2);stack1.push(1);stack1.push(2);stack1.push(3);stack1.push(4);stack1.pop();cout << stack1.top();return 0;
}
3、SLT实现Vector类
#include<iostream>
using namespace std;template<class T>
class Vector
{
public:Vector(int size = 10){_first = new T[size];_last = _first;_end = _first + size;}~Vector(){delete[]_first;_first = _last = _end = nullptr;}Vector(const Vector<T>& rhs){int size = rhs._end - rhs._first;_first = new T[size]; //空间大小int len = rhs._last - rhs._first;for (int i = 0; i < len; i++){_first[i] = rhs._first[i];}_last = _first + len;_end = _first + size;}Vector<T>& operator=(const Vector<T>& rhs) //拷贝构造{if (this == &rhs)return *this;delete[] _first;int size = rhs._end - rhs._first;int len = rhs._last - rhs._first;for (int i = 0; i < len; i++){_first[i] = rhs._first[i];}_last = _first + len;_end = _first + size;return *this;}void push_back(const T& val){if (full()){expand();}*_last = val;_last++;}void pop_back(){if (empty()){return;}--_last;}T back()const //返回容器末尾的元素值{return *(_last - 1);}bool full()const { return _last == _end; }bool empty()const { return _first == _last; }int size()const { return _last - _first; }private:void expand(){int _size = _end - _first;T* tmp = new T[_size * 2];for (int i = 0; i < _size; i++){tmp[i] = _first[i];}delete[]_first;_first = tmp;_last = _first + _size;_size *= 2;_end = _first + _size;}T* _first; //指向数组的起始的位置T* _last; //指向数组有效元素的后继位置T* _end; //指向数组空间的后继位置};
//容器空间分配器
class Test
{
public:Test() { cout << "test()" << endl; }~Test() { cout << "~test()" << endl; }
};int main()
{/*Vector<int>vec;for (int i = 0; i < 20; i++){vec.push_back(rand() % 100);}while (!vec.empty()){cout << vec.back() << " ";vec.pop_back();}cout << endl;vec.push_back(10);cout << vec.back() << endl;cout << endl;*/Vector<Test>vec;return 0;
}
6、容器空间配置
#include<iostream>
using namespace std;/*
template <class _Ty,class _Alloc = allocator<_Ty>>class Vector容器的空间配置器allocator做四件事情 内存开辟 内存释放 对象构造 对象析构
*///定义容器的空间配置器,和c++标准库的allocator实现一样
template<typename T>
class Allocator
{
public:T* allocate(size_t size) //负责内存开辟{return (T*)malloc(sizeof(T) * size);}void deallocate(void* p) //负责内存释放{free(p);}void construct(T* p, const T& val) //负责对象构造{new (p) T(val);//定位new}void destroy(T* p)//负责对象析构{p->~T();//代表了T类型的析构函数}
};
template<typename T, typename Alloc = Allocator<T>>
class Vector
{
public:Vector(int size = 10){//需要把内存开辟和对象构造分开处理//_first = new T[size];_first = _allocator.allocate(size);_last = _first;_end = _first + size;}~Vector(){//delete[]_first;//析构有效的元素,然后释放_first指针指向的堆内存for (T* p = _first; p != _last; p++){_allocator.destroy(p); //把first指针指向的数组的有效元素进行析构操作}_allocator.deallocate(_first);//释放堆上的数组内存_first = _last = _end = nullptr;}Vector(const Vector<T>& rhs){int size = rhs._end - rhs._first;//_first = new T[size]; //空间大小_first = _allocator.allocate(size);int len = rhs._last - rhs._first;for (int i = 0; i < len; i++){//_first[i] = rhs._first[i];_allocator.construct(_first + i, rhs._first[i]);}_last = _first + len;_end = _first + size;}Vector<T>& operator=(const Vector<T>& rhs) //拷贝构造{if (this == &rhs)return *this;//delete[] _first;for (T* p = _first; p != _last; p++){_allocator.destroy(p); //把first指针指向的数组的有效元素进行析构操作}_allocator.deallocate(_first);//释放堆上的数组内存int size = rhs._end - rhs._first;int len = rhs._last - rhs._first;for (int i = 0; i < len; i++){//_first[i] = rhs._first[i];_allocator.construct(_first + i, rhs._first[i]);}_last = _first + len;_end = _first + size;return *this;}void push_back(const T& val){if (full()){expand();}//*_last = val;_allocator.construct(_last, val);_last++;}void pop_back(){if (empty()){return;}//--_last;--_last;_allocator.destroy(_last);}T back()const //返回容器末尾的元素值{return *(_last - 1);}bool full()const { return _last == _end; }bool empty()const { return _first == _last; }int size()const { return _last - _first; }private:void expand(){int _size = _end - _first;//T* tmp = new T[_size * 2];T* tmp = _allocator.allocate(2 * _size);for (int i = 0; i < _size; i++){//tmp[i] = _first[i];_allocator.construct(tmp + i, _first[i]);}//delete[]_first;for (T* p = _first; p != _last; p++){_allocator.destroy(p);}_allocator.deallocate(_first);_first = tmp;_last = _first + _size;_end = _first + 2 * _size;}T* _first; //指向数组的起始的位置T* _last; //指向数组有效元素的后继位置T* _end; //指向数组空间的后继位置Alloc _allocator;//定义i容器中的空间配置项};
//容器空间分配器
class Test
{
public:Test() { cout << "test()" << endl; }~Test() { cout << "~test()" << endl; }Test(const Test&) { cout << "Test(const Test&)" << endl; }
};int main()
{Test t1, t2, t3;cout << "----------" << endl;Vector<Test>vec;vec.push_back(t1);vec.push_back(t2);vec.push_back(t3);cout << "----------" << endl;vec.pop_back(); //只需要析构cout << "----------" << endl;return 0;
}