- 一模板函数
- 1 一般模板函数
- 1.1代码实现
- 1.2 运行截图
- 1.3 小结
- 2 特化模板函数
- 2.1 代码实现
- 2.2 运行截图
- 2.3 小结
- 二 模板类Queue或Stack
- 1 模板类
- 1.1 代码实现
- 1.2运行截图
- 1.3 小结
- 2 成员模板函数
- 2.1代码实现
- 2.2运行截图
- 2.3 小结
- 3 模板特化
- 3.1 代码实现
- 3.2 运行截图
- 3.3 小结
- 三 模板类AutoPtr
- 1 代码实现
- 2 运行截图
- 3 小结
templateint compare(const T& left, const T& right) { if (left < right) return -1; else if (left > right) return 1; else return 0; } template int compare(T(&v1)[size], T(&v2)[size]) { for (int i = 0; i <= size;i++) { if (v1[i] > v2[i]) return 1; else if (v1[i] < v2[i]) return -1; } return 0; } int main(int argc, char** argv) { cout<< compare(1, 2)< 1.2 运行截图 1.3 小结 显然我们可以用该一般模板函数进行大部分同类型数值的比较,template
2 特化模板函数 2.1 代码实现用于单个数据,而template 用于数组,但当类型为const char*时通过该函数简单的< > =是无法对这种特殊类型数值大小进行正确比较,所以大部分类型比较用一般模板函数即可,而特殊的类型比较应该用特化模板函数。 #include < iostream> #include#include #include "CMatrix.h" using namespace std; template int compare(const T& left, const T& right) { if (left < right) return -1; else if (left > right) return 1; else return 0; } template int compare(T(&v1)[size], T(&v2)[size]) { for (int i = 0; i <= size;i++) { if (v1[i] > v2[i]) return 1; else if (v1[i] < v2[i]) return -1; } return 0; } template < > int compare (const char* const& v1, const char* const& v2) { return strcmp(v1, v2); } int main(int argc, char** argv) { cout<< compare(1, 2)< 2.2 运行截图 2.3 小结 templateint compare(const T& left, const T& right) templateint compare(T(&v1)[size], T(&v2)[size]) template < > int compare(const char* const& v1, const char* const& v2) { return strcmp(v1, v2); } 3个compare的模板函数已经可以比较好的解决绝大部分数据的正确比较。
二 模板类Queue或Stack 1 模板类 1.1 代码实现queue.h文件:
#ifndef QUEUE_H #define QUEUE_H #includeusing namespace std; //定义类模板 template class 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(0), tail(0) { 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() { destroy(); } 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 << p->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 destroy(); void copy_items(const Queue&); template void copy_items(It beg, It end); }; 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指针指向该元素 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) { destroy(); copy_items(q); } template template void Queue ::assign(It beg, It end) { destroy(); copy_items(beg, end); } template template void Queue ::copy_items(It beg, It end) { while (beg != end) { push(*beg); ++beg; } } //销毁队列 template void Queue ::destroy() { while (!empty()) { pop(); } } void TestQueue(); #endif main.cpp文件:
#include1.2运行截图 1.3 小结#include "queue.h" using namespace std; int main() { Queue qt; qt.push(8); qt.push(6); qt.push(2); cout << qt; return 0; } 类模板的使用能使用户为类定义一种模式,使得类中的某些数据出成员、某些成员函数的参数、返回值或局部变量能取不同类型(包括系统预定义的和用户自定义的),使一些类灵活性和通用性更高。
2 成员模板函数 2.1代码实现实现代码
//成员模板函数的实现 templateQueue(It beg, It end) : head(0), tail(0) { copy_items(beg, end); } //成员模板函数的实现 template template void Queue ::copy_items(It beg, It end) { while (beg != end) { //将数组中下标对应的值添加到队列中 push(*beg); ++beg; } } 测试代码
int a[5] = { 1,2,3,4,5 }; Queue2.2运行截图 2.3 小结q(a,a+5); cout << q; 通过成员模板函数让该类的适用性更强,让类中的一个函数可以处理多种类型参数变量。
3 模板特化 3.1 代码实现具体实现
template <> void Queue::push(const char* const& val) { char* new_item = new char[strlen(val) + 1]; //将val的值赋值到new_item,其中strlen(val)为需要复制的长度 strncpy_s(new_item,strlen(new_item),val, strlen(val)); QueueItem * pt = new QueueItem (new_item); if (empty()) { head = tail = pt; } else { tail->next = pt; tail = pt; } } template <> void Queue ::pop() { QueueItem * p = head; delete head->item; head = head->next; delete p; } 测试代码
Queue3.2 运行截图 3.3 小结q1; q1.push("www"); q1.push("hhc"); q1.push("6666"); cout << q1; 特殊类型可以调用模板特化函数来实现一般模板不能实现的效果。
三 模板类AutoPtr 1 代码实现具体实现
#ifndef AUTOPTR_H #define AUTOPTR_H templateclass AutoPtr { public: //构造函数 AutoPtr(T* pData); //拷贝构造函数 AutoPtr(const AutoPtr & h); //声明周期结束时调用析构函数 ~AutoPtr(); //等号的重载 AutoPtr & operator=(const AutoPtr & h); //用户数减1 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; //用户数加1 (*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 测试代码
AutoPtr2 运行截图 3 小结h1(new CMatrix); double data[10] = { 1,2,3,4,5,6,7,8,9,10 }; //生成一个2行5列的数组 h1->Create(2, 5, data); cout << *h1 << endl; //h2(拷贝构造函数的使用)和h1指向的是同一个地方 AutoPtr h2(h1); (*h2).Set(0, 1, 10); cout << *h1 << *h2 << endl; AutoPtr类似于Java中对象管理机制的智能指针类,它能够实时监测对象的用户数量,并控制其生命周期的结束(当对象的用户数为0时释放该对象所占用的内存)。



