类模板声明
1
2
3
4
5
6
7
8
9
10
11
12
13
14
<code>//通常形式</code>
<code>template</code> <code><</code><code>typename</code> <code>TypeParam></code>
<code>class</code> <code>SomeClass</code>
<code>{</code>
<code> </code><code>//...SomeClass的成员</code>
<code>};</code>
<code>//或者</code>
<code>template</code> <code><</code><code>typename</code> <code>TypeParam1,...,</code><code>typename</code> <code>TypeParamn></code>
在这些形式中,TypeParam是命名将要存储在容器类SomeClass中的数据的类型的通用类型参数,而关键词typename可以被替换为class。
注意
??1.关键词template规定了后面接着的是一个类的模式,而不是一个实际的类声明
? ?2.在类型形参列表中关键词tpyename和class可以互换使用
? ?3.和规则类的函数成员不同,在使用类模板时,编译器必须能够找到他的函数成员的定义。一种通常的方法是将所有函数定义从实现文件ClassName.cpp中移到ClassName.h中类声明后面。另一种方法是将函数定义放在单独的文件中然后再ClassName.h的最后#include这个文件。
? ?一个类模板仅仅是描述如何根据给定的类型那个构建不同的类的一个模式,这个创建一个类的过程被称为实例化。这是通过附加一个实际类型到对象定义中的类名上来实现的:
<code>SomeClass<Actual_Type> object;</code>
? ?例如,可以使用下面的定义来实例化Stack这个类模板:
<code>Stack<</code><code>char</code><code>> charStack;</code>
<code>Stack<</code><code>char</code><code>> dubStack;</code>
? ?当编译器处理这些声明时,他将产生两个不同的Stack类(两个实例),一个是使用char代替了StackElement,另一个是使用double代替了StackElement。第一个类中的构造函数将构造charStack为一个空的字符型的栈,而第二个类中的构造函数将构造dubStack为一个空的double型的栈。
有3条重要的规则规定了如何创建类模板:
? ?1.所有定义在类声明之外的操作都必须是模板函数
? ?2.任何将一个模板类的名作为类型的使用都必须参数化
? ?3.当使用类模板时,编译器必须能够找到它的操作的定义
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<code>template</code> <code><</code><code>typename</code> <code>StackElement></code>
<code>class</code> <code>Stack</code>
<code> </code><code>//复制构造函数</code>
<code> </code><code>Stack(</code><code>const</code> <code>Stack<StackElement>& original);</code>
<code> </code><code>//赋值运算符</code>
<code> </code><code>const</code> <code>Stack<StackElement>& operator=(</code><code>const</code> <code>Stack<StackElement>& original);</code>
<code> </code><code>//somecode</code>
<code>Stack<StackElement>::Stack()</code>
<code> </code><code>// 构造函数的定义</code>
<code>}</code>
<code>Stack<StackElement>::Stack(</code><code>const</code> <code>Stack<StackElement>& original)</code>
<code>//---operator<<()</code>
<code>inline</code> <code>ostream& operator<<(ostream& out,</code><code>const</code> <code>Stack<StackElement>& st)</code>
一个Stack类模板
<code>#include <iostream></code>
<code>#include <cassert></code>
<code>using</code> <code>namespace</code> <code>std;</code>
<code>#ifndef DSTACK</code>
<code>#define DSTACK</code>
<code>public</code><code>:</code>
<code> </code><code>Stack(</code><code>int</code> <code>numElements = 128);</code>
<code> </code><code>~Stack();</code>
<code> </code><code>const</code> <code>Stack<StackElement>& operator =(</code><code>const</code> <code>Stack<StackElement>& rightHandSide);</code>
<code> </code><code>bool</code> <code>empty() </code><code>const</code><code>;</code>
<code> </code><code>void</code> <code>push(</code><code>const</code> <code>StackElement& value);</code>
<code> </code><code>void</code> <code>display(ostream& out) </code><code>const</code><code>;</code>
<code> </code><code>StackElement top() </code><code>const</code><code>;</code>
<code> </code><code>void</code> <code>pop();</code>
<code>private</code><code>:</code>
<code> </code><code>int</code> <code>myCapacity;</code>
<code> </code><code>int</code> <code>myTop;</code>
<code> </code><code>StackElement* myArray;</code>
对应的cpp文件
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
107
108
109
110
111
112
113
114
115
116
117
118
119
<code>#include <new></code>
<code>Stack<StackElement>::Stack(</code><code>int</code> <code>numElements)</code>
<code> </code><code>assert</code><code>(numElements>0);</code>
<code> </code><code>myCapacity = numElements;</code>
<code> </code><code>myArray = </code><code>new</code><code>(</code><code>nothrow</code><code>) StackElement[myCapacity];</code>
<code> </code><code>if</code><code>(myArray != 0)</code>
<code> </code><code>myTop = -1;</code>
<code> </code><code>else</code>
<code> </code><code>{</code>
<code> </code><code>cerr << </code><code>"Inadequate memort to allocate stack !\n"</code> <code><< </code><code>" -- terminating execution !\n"</code><code>;</code>
<code> </code><code>exit</code><code>(1);</code>
<code> </code><code>}</code>
<code>Stack<StackElement>::Stack(</code><code>const</code> <code>Stack<StackElement> &original):myCapacity(original.myCapacity),myTop(original.myTop)</code>
<code> </code><code>for</code><code>(</code><code>int</code> <code>pos=0;pos<=myTop;pos++)</code>
<code> </code><code>myArray[pos] = original.myArray[pos];</code>
<code> </code><code>cerr << </code><code>"Inadequate memort to allocate stack !\n"</code><code>;</code>
<code>inline</code> <code>Stack<StackElement>::~Stack()</code>
<code> </code><code>delete</code><code>[] myArray;</code>
<code>const</code> <code>Stack<StackElement>& Stack<StackElement>::operator =(</code><code>const</code> <code>Stack<StackElement>& rightHandSide)</code>
<code> </code><code>if</code><code>(</code><code>this</code> <code>!= &rightHandSide)</code>
<code> </code><code>if</code><code>(myCapacity != rightHandSide.myCapacity)</code>
<code> </code><code>{</code>
<code> </code><code>delete</code><code>[] myArray;</code>
<code> </code><code>myCapacity = rightHandSide.myCapacity;</code>
<code> </code><code>myArray = </code><code>new</code> <code>StackElement[myCapacity];</code>
<code> </code><code>if</code><code>(myArray == 0)</code>
<code> </code><code>{</code>
<code> </code><code>cerr << </code><code>"Inadequate memory !\n"</code><code>;</code>
<code> </code><code>exit</code><code>(1);</code>
<code> </code><code>}</code>
<code> </code><code>}</code>
<code> </code><code>myTop = rightHandSide.myTop;</code>
<code> </code><code>myArray[pos] = rightHandSide.myArray[pos];</code>
<code> </code><code>return</code> <code>*</code><code>this</code><code>;</code>
<code>inline</code> <code>bool</code> <code>Stack<StackElement>::empty() </code><code>const</code>
<code> </code><code>return</code> <code>(myTop == -1);</code>
<code>inline</code> <code>void</code> <code>Stack<StackElement>::push(</code><code>const</code> <code>StackElement &value)</code>
<code> </code><code>if</code><code>(myTop < myCapacity-1)</code>
<code> </code><code>++myTop;</code>
<code> </code><code>myArray[myTop] = value;</code>
<code> </code><code>cerr << </code><code>"Stack full, can‘t add new value‘ !\n"</code><code>;</code>
<code>inline</code> <code>void</code> <code>Stack<StackElement>::display(ostream &out) </code><code>const</code>
<code> </code><code>for</code><code>(</code><code>int</code> <code>i=myTop;i>=0;i--)</code>
<code> </code><code>out << myArray[i] << endl;</code>
<code>inline</code> <code>ostream& operator <<(ostream& out,</code><code>const</code> <code>Stack<StackElement>& st)</code>
<code> </code><code>st.display(out);</code>
<code> </code><code>return</code> <code>out;</code>
<code>inline</code> <code>StackElement Stack<StackElement>::top() </code><code>const</code>
<code> </code><code>if</code><code>(!empty())</code>
<code> </code><code>return</code> <code>(myArray[myTop]);</code>
<code> </code><code>cerr << </code><code>"Stack is empty -- returning garbage value\n"</code><code>;</code>
<code> </code><code>StackElement garbage;</code>
<code> </code><code>return</code> <code>garbage;</code>
<code>inline</code> <code>void</code> <code>Stack<StackElement>::pop()</code>
<code> </code><code>if</code><code>(myTop >= 0)</code>
<code> </code><code>myTop--;</code>
<code> </code><code>cerr << </code><code>"Stack is empty -- can‘t remove a value\n"</code><code>;</code>
?