類模板聲明ios
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
//一般形式
template
<
typename
TypeParam>
class
SomeClass
{
//...SomeClass的成員
};
//或者
template
<
typename
TypeParam1,...,
typename
TypeParamn>
class
SomeClass
{
//...SomeClass的成員
};
|
在這些形式中,TypeParam是命名將要存儲在容器類SomeClass中的數據的類型的通用類型參數,而關鍵詞typename可以被替換爲class。ide
注意函數
1.關鍵詞template規定了後面接着的是一個類的模式,而不是一個實際的類聲明this
2.在類型形參列表中關鍵詞tpyename和class可以互換使用
spa
3.和規則類的函數成員不一樣,在使用類模板時,編譯器必須能夠找到他的函數成員的定義。一種一般的方法是將所有函數定義從實現文件ClassName.cpp中移到ClassName.h中類聲明後面。還有一種方法是將函數定義放在單獨的文件裏而後再ClassName.h的最後#include這個文件。
code
一個類模板不過描寫敘述怎樣依據給定的類型那個構建不一樣的類的一個模式,這個建立一個類的過程被稱爲實例化。這是經過附加一個實際類型到對象定義中的類名上來實現的:
orm
1
|
SomeClass<Actual_Type> object;
|
好比,可以使用如下的定義來實例化Stack這個類模板:對象
1
2
|
Stack<
char
> charStack;
Stack<
char
> dubStack;
|
當編譯器處理這些聲明時,他將產生兩個不一樣的Stack類(兩個實例),一個是使用char取代了StackElement,還有一個是使用double取代了StackElement。第一個類中的構造函數將構造charStack爲一個空的字符型的棧,而第二個類中的構造函數將構造dubStack爲一個空的double型的棧。
ci
有3條重要的規則規定了怎樣建立類模板:
rem
1.所有定義在類聲明以外的操做都必須是模板函數
2.不論什麼將一個模板類的名做爲類型的使用都必須參數化
3.當使用類模板時,編譯器必須能夠找到它的操做的定義
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
|
template
<
typename
StackElement>
class
Stack
{
//複製構造函數
Stack(
const
Stack<StackElement>& original);
//賦值運算符
const
Stack<StackElement>& operator=(
const
Stack<StackElement>& original);
//somecode
};
template
<
typename
StackElement>
Stack<StackElement>::Stack()
{
// 構造函數的定義
}
template
<
typename
StackElement>
Stack<StackElement>::Stack(
const
Stack<StackElement>& original)
{
//複製構造函數
}
//---operator<<()
template
<
typename
StackElement>
inline
ostream& operator<<(ostream& out,
const
Stack<StackElement>& st)
{
//somecode
}
|
一個Stack類模板
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
|
#include <iostream>
#include <cassert>
using
namespace
std;
#ifndef DSTACK
#define DSTACK
template
<
typename
StackElement>
class
Stack
{
public
:
Stack(
int
numElements = 128);
Stack(
const
Stack<StackElement>& original);
~Stack();
const
Stack<StackElement>& operator =(
const
Stack<StackElement>& rightHandSide);
bool
empty()
const
;
void
push(
const
StackElement& value);
void
display(ostream& out)
const
;
StackElement top()
const
;
void
pop();
private
:
int
myCapacity;
int
myTop;
StackElement* myArray;
};
|
相應的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
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
|
#include <new>
template
<
typename
StackElement>
Stack<StackElement>::Stack(
int
numElements)
{
assert
(numElements>0);
myCapacity = numElements;
myArray =
new
(
nothrow
) StackElement[myCapacity];
if
(myArray != 0)
myTop = -1;
else
{
cerr <<
"Inadequate memort to allocate stack !\n"
<<
" -- terminating execution !\n"
;
exit
(1);
}
}
template
<
typename
StackElement>
Stack<StackElement>::Stack(
const
Stack<StackElement> &original):myCapacity(original.myCapacity),myTop(original.myTop)
{
myArray =
new
(
nothrow
) StackElement[myCapacity];
if
(myArray != 0)
for
(
int
pos=0;pos<=myTop;pos++)
myArray[pos] = original.myArray[pos];
else
{
cerr <<
"Inadequate memort to allocate stack !\n"
;
exit
(1);
}
}
template
<
typename
StackElement>
inline
Stack<StackElement>::~Stack()
{
delete
[] myArray;
}
template
<
typename
StackElement>
const
Stack<StackElement>& Stack<StackElement>::operator =(
const
Stack<StackElement>& rightHandSide)
{
if
(
this
!= &rightHandSide)
{
if
(myCapacity != rightHandSide.myCapacity)
{
delete
[] myArray;
myCapacity = rightHandSide.myCapacity;
myArray =
new
StackElement[myCapacity];
if
(myArray == 0)
{
cerr <<
"Inadequate memory !\n"
;
exit
(1);
}
}
myTop = rightHandSide.myTop;
for
(
int
pos=0;pos<=myTop;pos++)
myArray[pos] = rightHandSide.myArray[pos];
}
return
*
this
;
}
template
<
typename
StackElement>
inline
bool
Stack<StackElement>::empty()
const
{
return
(myTop == -1);
}
template
<
typename
StackElement>
inline
void
Stack<StackElement>::push(
const
StackElement &value)
{
if
(myTop < myCapacity-1)
{
++myTop;
myArray[myTop] = value;
}
else
{
cerr <<
"Stack full, can't add new value' !\n"
;
exit
(1);
}
}
template
<
typename
StackElement>
inline
void
Stack<StackElement>::display(ostream &out)
const
{
for
(
int
i=myTop;i>=0;i--)
out << myArray[i] << endl;
}
template
<
typename
StackElement>
inline
ostream& operator <<(ostream& out,
const
Stack<StackElement>& st)
{
st.display(out);
return
out;
}
template
<
typename
StackElement>
inline
StackElement Stack<StackElement>::top()
const
{
if
(!empty())
return
(myArray[myTop]);
else
{
cerr <<
"Stack is empty -- returning garbage value\n"
;
StackElement garbage;
return
garbage;
}
}
template
<
typename
StackElement>
inline
void
Stack<StackElement>::pop()
{
if
(myTop >= 0)
myTop--;
else
cerr <<
"Stack is empty -- can't remove a value\n"
;
}
|