C++学习------模板

来源:互联网 发布:类似于灵魂摆渡网络剧 编辑:程序博客网 时间:2024/05/17 01:35

 模板<template>



 本篇博客阐述主要内容有:

 1.模板的定义
 2.模板函数
 3.模板类
 4.C++容器


-----------------------------------------------------


   模板:望文生义,就是一个模子,在C++中提供重用源代码的方法;


   函数的重载,就是解决函数接收不同类型的参数的问题而产生的,但是,我们往往是不愿意这样做的,因为这样的话,等于多写了一份代码,拉长了代码长度,于是,就有了模板的存在,模板只需要你写一份代码就可以实现不同类型数据的复;模板的一般使用方式是: template<class T,...>或者template<typename T,...> 尖括号里的模板参数;


例如下面这个简单的例子<函数模板>: 

#include<iostream>#include<string>using namespace std;template<typename T>bool Equal(const T& a,const T& b){return a==b;}int main(){cout<<Equal<int>(1,2)<<endl;//注意使用的方式,<传参类型>cout<<Equal<int>(1.1,2)<<endl; //错误! 注意模板参数的匹配cout<<Equal<string>("aaaaa","aaaaa")<<endl;//不同类型的参数system("pause");return 0;}

 这样就实现了不同类型参数的函数调用,那么,模板函数实现的机制是什么呢?


其实,这些事情都是编译器在默默的帮你完成. 






 模板类


 我们知道类的实现也依赖于类成员的基本类型,那么模板是怎样实现类的呢?


 举个简单例子:


#include<iostream>using namespace std;template<class T = int>// class 或者 typename 是一样的,类的模板参数可以有默认参数;class Seqlist{T _data;int _size;int _capacity;public:Seqlist (const T& data,const int size,const int capacity):_data(data),_size(size),_capacity(capacity );{}};


  写过顺序表的同学都知道,顺序表中的数据类型我们一般写的都是int,或者宏定义一下数据类型,为了方便以后数


据类型的修改,但是其实还是很麻烦的,而我再上面简单的用模板参数实现了顺序表数据成员的定义,这样后面所有


的类型都是T类型的;这样,同学们也可以试着用模板参数实现顺序表和链表;


  模板的能力远不止这样,以后我会写关于类型萃取<模板的特化>的博客也是用的模板,还有已经写过的智能指针中


也用了模板!


  《浅析智能指针一》

  《浅析智能指针二》

 在C++中有容器这样一个概念,比如我们所知道的栈和队列,我在下面贴出模板参数实现栈和队列的模拟实现:

-------------------------------------------------------------------------------------

 模板参数实现栈

#include<iostream>#include<string>#include<cassert>using namespace std;template<class T>class SeqList{public:SeqList ():_pdata(NULL),_size(0),_capacity(3){_pdata = new T[3];}~SeqList (){if(_pdata != NULL){delete[] _pdata;_size = 0;_capacity = 0;}}void Display(){for(int i = 0; i<_size; i++){cout<<_pdata[i]<<" ";}cout<<endl;}void PushBack(const T& data);void PushFront(const T& data);void PopBack();void PopFront();void Sort();int Find(const T& P);void Intsert(const int& pos,const T& data);void Remove(const T& data);void RemoveAll(const T& data);T& operator[](int size){assert(size<_size);assert(size>=0);return _pdata[size];} public:void CheckCapacity(){int NewCapacity = _capacity*2 + 3;if(_size == _capacity){T* tmp = new T[NewCapacity];for(int i = 0; i<_size; i++){tmp[i] = _pdata[i];}delete[] _pdata;_pdata = tmp;_capacity = NewCapacity ;}}T* _pdata;int _size;int _capacity;};template<typename T>int SeqList <T>::Find(const T& data){int i = 0;for(i= 0 ; i < _sz; i++){if(_pdata[i] == data)//注意这里的等号,千万别写成赋值等;return i;}return -1;}template<typename T>void SeqList<T>:: PushBack(const T& data){CheckCapacity ();_pdata[_size] = data;_size++;}template<class T>void SeqList<T>::PushFront(const T& data){    CheckCapacity();int length =  _size;while(length){_pdata[length]=_pdata[length-1];length--;}_pdata[0] = data;_size++;}template<typename T>void SeqList <T>::PopBack (){if(_size>=1){_size-=1;}}template<typename T>void SeqList <T>::PopFront(){int len = 0;while(len<_size-1){_pdata[len] = _pdata[len+1];len++;}_size--;}template<typename T>void SeqList <T>::Intsert(const int& pos, const T& data){CheckCapacity ();int index = Find(pos);if(index>=0){int length = _size;while(length > index){_pdata[length]=_pdata[length-1];length--;}_pdata[index] = data;_size++;}}template<typename T>void SeqList <T>::Remove(const T& data){int index = Find(data);if(index>=0){while(index<_size-1){_pdata[index] = _pdata[index+1];index++; }}_size--;}template<typename T>void SeqList <T>::RemoveAll (const T& data){while(Find(data)>=0){Remove(data);}}template<typename T>void SeqList <T>::Sort (){for(int i = 0; i<_size-1; i++){for(int j = 0; j < _size-i-1; j++){if(_pdata[j]<_pdata[j+1]){T tmp = _pdata [j];_pdata [j] = _pdata [j+1];_pdata [j+1] = tmp;}}}}template<typename T, typename Container>class Stack{public:void Push(const T& data){_con.PushBack(data);}T& Top(){int sz = _con._size - 1;return _con._pdata[sz];}bool Empty(){return _con._size == 0;}void Pop(){_con.PopBack();}void Display(){while(!Empty()){cout<<Top()<<"  ";Pop();}}private:Container _con;};void test(){SeqList<string> s;SeqList<int> s1;s1.PushBack(2);s1.PushBack(5);s1.PushBack(4);s1.PushBack(6);s.PushBack ("aaaaaaaaaaaaaa");s.PushBack ("dsadsas");s.PushBack ("ssssssssssss");s.PushBack ("sdasadadafffffffffffffffffffffffffffffffffff");s.PushBack ("sdasdas");s1.Sort ();s1.Display ();}void test1(){Stack<int , SeqList<int>> s;s.Push (1);s.Push (1);s.Push (3);s.Push (4);s.Push (2);s.Display ();}int main(){test1();system("pause");return 0;}


-----------------------------------------------------------------------------------------------------

模板参数实现队列


// 模板参数模拟实现队列#include<iostream>using namespace std;template<typename T>struct Node{Node(const T& d):_next(NULL),_prev(NULL),_data(d){}T _data;Node<T>* _next;Node<T>* _prev;};template<typename T>class LinkList{public:LinkList ():_head(NULL),_tail(NULL){}~LinkList (){Node<T>* cur =_head;while(cur){Node<T>* tmp = cur;cur = cur->_next ;delete tmp;}_head = _tail = NULL;}void PushBack(const T& data);void PushFront(const T& data);void PopBack();void PopFront();void Remove(const T& data);void RemoveAll(const T& data);void Sort();void Display();Node<T>* GetHead(){return _head;}private:Node<T>* _head;Node<T>* _tail;};template<typename T>void LinkList<T>::PushBack(const T& data){Node<T>* pNode = new Node<T>(data);if(_head==NULL){_head = _tail = pNode; }else{_tail->_next = pNode;pNode->_prev = _tail;_tail = pNode ;}}template<typename T>void LinkList <T>::PushFront(const T& data){Node<T>* pNode = new Node<T>(data);if(_head==NULL){_head = _tail = pNode;}else{pNode->_next = _head;_head->_prev = pNode;_head = pNode;}}template<typename T>void LinkList <T>::PopBack (){if(_head==NULL)return;else if(_head->_next == NULL){delete _head;_head = _tail = NULL;}else{Node<T>* tmp = _tail;    _tail = _tail->_prev ;    _tail->_next = NULL;    delete tmp;}}template<typename T>void LinkList <T>::PopFront (){if(_head==NULL)return;Node<T>* tmp = _head;_head->_prev = NULL;_head = _head->_next ;delete tmp;}template<typename T>void LinkList <T>::Remove (const T& data){Node<T>* cur = _head;while(cur){if(cur->_data == data){if(cur->_prev == NULL){PopFront ();}else if(cur->_next == NULL){PopBack ();}else{Node<T>* t = cur;cur->_next ->_prev = cur->_prev ;cur->_prev ->_next = cur->_next ;delete t;}return;}cur = cur->_next ;}}template<typename T>void LinkList<T>::RemoveAll (const T& data){Node<T>* cur = _head;while(cur){if(cur->_data == data){if(cur == _head){cur = cur->_next ;PopFront ();}else if(cur->_next == NULL){PopBack ();cur = NULL;break;}else{/*Node<T>* t = cur->_next;cur->_next ->_prev = cur->_prev ;cur->_prev ->_next = cur->_next ;delete cur;cur = t;*/cur->_data = _tail->_data ;PopBack();}}elsecur = cur->_next ;}}template<typename T>void LinkList <T>::Sort (){//链表的冒泡排序;   Node<T>* cur = NULL;   Node<T>* teil = NULL;cur = _head ;while(cur != teil){while(cur->_next != teil){if(cur->_data > cur->_next ->_data ){T tmp = cur->_data ;cur->_data = cur->_next ->_data ;cur->_next ->_data = tmp;}cur = cur->_next ;}teil = cur;cur = _head;}return ;}template<typename T>void LinkList<T>::Display(){Node<T>* tmp = _head;while(tmp){cout<<tmp->_data<<"  ";tmp = tmp->_next;}cout<<endl;}template<typename T,typename Container>class Queue{public:bool Empty(){return _con.GetHead() == NULL;}Node<T>& Front(){return *_con.GetHead();  }void Back(const T& data){}void Push(const T& data){_con.PushBack(data);}void Pop(){_con.PopFront();}void Dispaly(){while(!Empty()){cout<<Front()._data<<endl;Pop(); }}private:Container _con;};void test1(){Queue<int , LinkList<int> > s;s.Push (1);s.Push (1);s.Push (1);s.Push (2);s.Dispaly ();}void  test(){LinkList<int> l;l.PushBack (1);l.PushBack (4);l.PushBack (2);l.PushBack (1);l.PushBack (2);l.PushBack (6);l.PushFront (4);l.Sort ();//l.Remove (1);//l.RemoveAll (3);//l.PopBack ();/*l.PopBack ();l.PushFront (4);l.PopFront ();*/l.Display ();}int main(){test1();system("pause");return 0;}


1 0