模板入门学习
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了模板入门学习相关的知识,希望对你有一定的参考价值。
template
1.定义模板时用template
2.template<typename T1,typename T2,....typename Tn>,尖括号里的参数可有有多个,即多个类型,用逗号隔开。
3.在使用模板的每个块都要加上模板声明。
4.在调用模板函数时,编译器自动生成多个重载函数。
例1. 简单函数
template<typename T> bool equal(const T & a, const T & b) { return a == b; } bool equal(const int a, const int b) { return a == b; }
在同时定义了模板函数和非模板函数,在调用时优先调用非模板的函数
例2. 顺序表
template<typename T> class SeqList { public: SeqList( int capacity =7) :_data( NULL) , _size(0) , _capacity( capacity) { _data = new T [_capacity]; } ~SeqList() { if (_data != NULL ) delete[]_data; } public: void CheckCapacity() { if (_size == _capacity) { T*tmp = new T[_capacity + 7]; memcpy(tmp, _data, _size*sizeof(T )); delete[] _data; _data = tmp; _capacity = _capacity + 7; } } public: void PushBack(const T&d); void PushFront(const T&d); void PopBack(); void PopFront(); void Print() { int i = 0; for (i = 0; i < _size; i++) { cout << _data[i] << " " ; } cout <<"over" << endl; } private: T* _data; T _size; T _capacity; }; template<typename T> void SeqList <T>::PushBack( const T &d) { CheckCapacity(); _data[_size] = d; _size++; } template<typename T> void SeqList <T>::PushFront( const T &d) { CheckCapacity(); T start = _size-1; while (start >= 0) { _data[start+1] = _data[start]; start--; } _data[0] = d; _size++; } template<typename T> void SeqList <T>::PopBack() { _size--; } template<typename T> void SeqList <T>::PopFront() { T start = 0; _data[0] = NULL; for (start = 0; start < _size; start++) { _data[start] = _data[start + 1]; } _size--; }
在main函数中使用模板时,指定模板中T的类型
int main() { SeqList<int >S1; S1.PushBack(1); S1.PushBack(3); S1.PopBack(); S1.Print(); S1.PushFront(5); S1.PopFront(); S1.Print(); getchar(); return 0; }
例3. 双向链表
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 Dlist { public: Dlist(); ~Dlist(); Dlist( const Dlist& d); Dlist & operator=(const Dlist&d); public: void PushFront(T const & d); void PopFront(); void PushBack(T const & d); void PopBack(); void Print(); void Reverse(); private: Node<T>*_head; Node<T>*_tail; }; template<typename T> Dlist<T>::Dlist() :_head(NULL) ,_tail(NULL) {} template<typename T> Dlist<T>::~Dlist() { Node<T>*cur = _head; while (cur) { Node<T>*del = cur; cur = cur->next; delete del; } } template<typename T> Dlist<T>::Dlist(const Dlist& d) :_head(NULL) , _tail(NULL) { Node<T>* cur = d._head; while (cur) { PushBack(cur->_data); cur = cur->next; } } template<typename T> void Dlist<T>::PushFront(T const & d) { Node<T>*newNode = new Node<T>(d); if (_head == NULL) { _head = newNode; _tail = newNode; } else { newNode->next = _head; _head->prev = newNode; _head = newNode; } } template<typename T> void Dlist<T>::PopFront() { if (_head == NULL) return; if (_head == _tail) { delete _head; _head = NULL; _tail = NULL; return; } Node<T>*del=_head; _head = _head->next; _head->prev = NULL; delete del; } template<typename T> void Dlist<T>::PushBack(T const & d) { Node<T>*newNode = new Node<T>(d); if (_head == NULL) { _head = newNode; _tail = newNode; } _tail->next = newNode; newNode->prev = _tail; _tail = newNode; } template<typename T> void Dlist<T>::PopBack() { if (_head == NULL) return; if (_tail == _head) { delete _head; _tail = NULL; _head = NULL; } _tail = _tail->prev; delete _tail->next; _tail->next = NULL; } template<typename T> void Dlist<T>::Print() { Node<T>*cur = _head; while (cur != NULL) { cout << cur->_data << "->"; cur = cur->next; } cout << "over"<< endl; } template<typename T> void Dlist<T>::Reverse() { if ((_head == _tail) || (_head == NULL)) return; Node<T>*cur = _head; while (cur->next) { swap(cur->next, cur->prev); cur = cur->prev; } swap(_head, _tail); }
类模板特化
1.全特化
在基于模板template<typename T>的版本上,重写其中某个特定的类型,在main中若调用了这个函数时,若是重写的这个特定类型,就调用重写的特定类型函数,而不调用模板函数。
2.偏特化/部分特化
(1). 特化其中一个
template<typename T1,typename T2> //..... template<typename T1> class Date<T1 ,int>
(2).特化两个参数为指针类型等
class Date<T1*,T2*>
模板的分离编译
在以往的程序编写中,把宏和函数声明放入头文件(*.h),函数定义放到(*.cpp)文件,函数的main函数等测试函数放到(test.cpp)中。但是模板函数不能分离编译,由于每个文件都是单独编译的,在创建类的文件中没有创建对象实例化,在测试的模板文件中没有类的声明,导致编译失败。
解决方案:把声明和定义均放到同一个文件中(*.hpp)。
友元operator函数在写成模板时只能放到类内实现
template <typename T> class Date { template<typename Type> friend ostream operator<<(ostream& os, const Data<Type>& d) { os << d ._d << endl; return os ; } public: //... private: T _d; //... };
本文出自 “无以伦比的暖阳” 博客,请务必保留此出处http://10797127.blog.51cto.com/10787127/1755480
以上是关于模板入门学习的主要内容,如果未能解决你的问题,请参考以下文章
Expression Blend实例中文教程(12) - 样式和模板快速入门Style,Template
Expression Blend实例中文教程(12) - 样式和模板快速入门Style,Template