
目录
模板的概念
函数模板
类模板
实验
一、模板函数(compare)
一般模板函数
特化模板函数
二、模板类Queue或Stack
queue.h
类模板的特化
模板成员函数特化
三、模板类AutoPtr
模板的概念
模板就是建立通用的模具,大大提高复用性
C++提供两种模板机制:函数模板和类模板
函数模板针对仅参数类型不同的函数;
类模板针对仅数据成员和成员函数类型不同的类。
函数模板-
template
函数声明或定义 -
使用函数模板有两种方式:自动类型推导、显示指定类型
- 建立一个通用类,类中的成员 数据类型可以不具体制定,用一个虚拟的类型来代表。
- template
类
类模板与函数模板区别主要有两点:
- 类模板没有自动类型推导的使用方式
- 类模板在模板参数列表中可以有默认参数
#include "mainwindow.h" #include#include template int compare(const Type &v1,const Type &v2) { if(v1 v2) return 1; return 0; } int main(int argc, char *argv[]) { const char *cp1="world",*cp2="hi"; int a=1,b=2; compare(a,b); compare(cp1,cp2); return 0; }
运行结果
特化模板函数当函数模板需要对某些类型进行特化处理,称为函数模板的特化。
template<> int compare(const char * const &v1, const char * const &v2) { cout<<"specialization"< 运行结果
同时,函数模版的特化,当函数调用发现有特化后的匹配函数时,会优先调用特化的函数,而不再通过函数模版来进行实例化。
二、模板类Queue或Stack类模板example
#include#include using namespace std; //类模板 template class Person { public: Person(T1 name, T2 age) { this->mName = name; this->mAge = age; } void showPerson() { cout << "name: " << this->mName << " age: " << this->mAge << endl; } public: T1 mName; T2 mAge; }; //1、类模板没有自动类型推导的使用方式 void test1() { Person p("xxd", 1000); //必须使用显示指定类型的方式,使用类模板 p.showPerson(); } //2、类模板在模板参数列表中可以有默认参数 void test2() { Person p("jmu", 999); //类模板中的模板参数列表 可以指定默认参数 p.showPerson(); } int main() { test1(); test2(); return 0; } 类模板和函数模板语法相似,在声明模板template后面加类,此类称为类模板
运行结果
queue
queue.h
- push():会将一个元素置入queue中;
- front():会返回queue内的第一个元素
- back():会返回queue中的最后一个元素
- pop():会移除queue内的第一个元素
#ifndef QUEUE_H #define QUEUE_H #include类模板的特化using namespace std; template class Queue; //先声明 Queue template class QueueItem{ QueueItem(const Type &t):item(t),next(0){} Type item; QueueItem *next; friend class Queue ;//友元函数 访问 friend ostream& operator<<(ostream& os,const Queue &q); //运算符重载 QueueItem * operator++(){ return next; } Type & operator*(){ return item; } }; template class Queue{ public: //定义构造器 Queue():head(0),tail(0){} Queue(const Queue& q):head(),tail(){ copy_items(q); } template Queue(It beg,It end):head(0),tail(0){ copy_items(beg,end); } template void assign(It beg,It end); Queue& operator=(const Queue&); //析构函数 ~Queue(){destory();} Type& front(){return head->item;} const Type& front() const {return head->item;} void push(const Type &); void pop(); bool empty() const { return head==0; } friend ostream& operator<<(ostream& os,const Queue &q){ os<<"< "; QueueItem *p; for(p=q.head;p;p=p->next){ os< item<<" "; } os <<">"; return os; } const QueueItem *Head() const{return head;} const QueueItem *End() const{return (tail==NULL)?NULL:tail->next ;} private: QueueItem *head; QueueItem *tail; void destory(); void copy_items(const Queue &); template void copy_items(It beg,It end); }; //成员模板函数 template void Queue ::destory(){ while(!empty()){ pop(); } } //移除第一个元素 template void Queue ::pop(){ QueueItem * p=head;//赋值头指针 head=head->next; //指向下一个指针 delete p; } //在尾部添加一个新的元素 template void Queue ::push(const Type& val){ QueueItem *pt =new QueueItem (val); if(empty()){ head=tail=pt; } else{ tail->next=pt; tail=pt; } } //模板成员函数特化 template<> void Queue ::push(const char * const &val); template<> void Queue ::pop(); template void Queue ::copy_items(const Queue &orig){ for(QueueItem *pt = orig.head;pt;pt=pt->next){ push(pt->item); } } template Queue & Queue ::operator=(const Queue& q) { destory(); copy_items(q); } template template void Queue ::assign(It beg, It end) { destory(); copy_items(beg,end); } template template void Queue ::copy_items(It beg,It end) { while(beg!=end){ push(*beg); ++beg; } } template int compare(const Type& v1, const Type& v2) { if(v1 v2) return 1; return 0; } template<> int compare (const char * const &v1, const char * const &v2); #endif // QUEUE_H 当类模板内需要对某些类型进行特别处理时,使用类模板的特化。
模板成员函数特化实现模板类Queue中的成员函数push()和pop()方法的特化版本,使其能够实现字符串的入队和出队 *** 作。
#include "Queue.h" #include#include #include using namespace std; template <> void Queue ::push( const char * const & str) { char * pVal = new char[strlen(str)+1]; strcpy(pVal,str); QueueItem * p = new QueueItem (pVal); if(empty()) { head = tail = p; } else { tail->next = p; tail = p; } } template<> void Queue ::pop() { if(empty()) { return; } QueueItem * p = head; head = head->next; delete []p->item; delete p; } 运行结果
三、模板类AutoPtr#ifndef AUTOPTR_H #define AUTOPTR_H templateclass AutoPtr { public: AutoPtr(T* pData); AutoPtr(const AutoPtr & h); //调用析构函数 ~AutoPtr(); AutoPtr & operator=(const AutoPtr & h); void decrUser(); T* operator ->() { return m_pData; } T& operator*() { return *m_pData; } const T& operator *() const { return *m_pData; } const T* operator -> () const { return m_pData; } private: T* m_pData; int* m_nUser; }; template < class T> AutoPtr ::AutoPtr(T* pData) { m_pData = pData; //初始化用户数为1 m_nUser = new int(1); } template < class T> AutoPtr ::AutoPtr(const AutoPtr & h) { m_pData = h.m_pData; m_nUser = h.m_nUser; (*m_nUser)++; } template < class T> AutoPtr & AutoPtr ::operator=(const AutoPtr & h) { decrUser(); m_pData = h.m_pData; m_nUser = h.m_nUser; (*m_nUser)++; } template < class T> void AutoPtr ::decrUser() { --(*m_nUser); if ((*m_nUser) == 0) { delete m_pData; m_pData = 0; delete m_nUser; m_nUser = 0; } } template < class T> AutoPtr ::~AutoPtr() { decrUser(); } #endif // AUTOPTR_H 明天在写
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)