一、类模板
类模板:将类定义中的数据类型参数化
类模板实际上是函数模板的推广,可以用相同的类模板来组建任意类型的对象集合
(一)、类模板的定义
template <类型形参表>
class <类名>
{ //类说明体 };
template <类型形参表>
<返回类型> <类名> <类型名表>::<成员函数1>(形参表)
{ //成员函数定义体 }
template <类型形参表>
<返回类型> <类名> <类型名表>::<成员函数2>(形参表)
{ //成员函数定义体 }
…
template <类型形参表>
<返回类型> <类名> <类型名表>::<成员函数n>(形参表)
{ //成员函数定义体 }
(二)、使用类模板
类模板的实例化:用具体的数据类型替换模板的参数以得到具体的类(模板类)
模板类也可以实例化为对象
用下列方式创建类模板的实例:
对于函数模板与类模板,模板参数并不局限于类型(类类型,基本类型,模板类实例),普通值也可以作为模板参数
二、Stack类的模板实现
在前面曾经分别使用C/C++实现了一个链栈,栈中只能放进int类型数据,现在使用模板来重新实现Stack,可以存放多种数据类型,分别使用自定义链栈方式以及自定义数组实现。
(一)、自定义链栈方式:
stack.h:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 | /************************************************************************* > File Name: stack.h > Author: Simba > Mail: [email protected] > Created Time: 2012年11月03日 星期六 19时28分25秒 ************************************************************************/ #include<iostream> Node(T invalue): m_Value(invalue), m_Next(NULL) {} T getValue() const Node < T > *getNext() const private: template < class T > Node < T >::~Node() " deleted " << endl; } template < class T > class Stack public: template < class T > void Stack < T >::push(const T &value) template < class T > T Stack < T >::pop() m_Head = m_Head->getNext(); template < class T > inline T Stack < T >::top() const } template < class T > inline int Stack < T >::count() const |
main.cpp:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | #include "stack.h" int main(void) int val; while (intstack1.count()) Stack < char >stringstack; stringstack.push('A'); char val2; |
可以看到虽然intstack2 没有pop 出元素,但程序结束时,局部对象会被析构,调用析构函数,在析构函数内delete 头指针,顺藤摸瓜一直找到最后一个节点,即首先压栈的节点,依次返回释放掉。
(二)、自定义数组方式
Stack2.h:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 | #ifndef _STACK2_H_ #define _STACK2_H_ #include <exception> template <typename T, int MAX_SIZE> void Push(const T &elem); template <typename T, int MAX_SIZE> template <typename T, int MAX_SIZE> template <typename T, int MAX_SIZE> elems_[++top_] = elem; template <typename T, int MAX_SIZE> --top_; template <typename T, int MAX_SIZE> return elems_[top_]; template <typename T, int MAX_SIZE> return elems_[top_]; template <typename T, int MAX_SIZE> |
main.cpp:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | #include "Stack2.h" #include <iostream> #include<string> using namespace std; int main(void) while (!s.Empty()) |
输出为 3 2 1
注意,用数组实现时pop 操作并没有删除元素的操作,只是移动了top 指针,下次push 的时候直接覆盖即可。再者因为实现了Top 返回栈顶元素,故pop 没有返回值。
参考:
C++ primer 第四版
Effective C++ 3rd
C++编程规范