📄 12章 模板.txt
字号:
31 }
32
33 // Push an element onto the stack
34 // return true if successful, false otherwise
35 template<class T>
36 bool Stack< T >::push( const T &pushValue )
37 {
38 if (!isFull() ) {
39 stackPtr[ ++top ] = pushValue; // place item in Stack
40 return true; // push successful
41 }
42 return false; // push unsuccessful
43 }
44
45 // Pop an element off the stack
46 template<class T>
47 bool Stack< T >::pop( T &popValue )
48 {
49 if (!isEmpty() ) {
50 popValue = stackPtr[ top-- ]; // remove item from Stack
51 return true; // pop successful
52 }
53 return ffalse; // pop unsuccessfu
54 }
55
56 #endif
57 // Fig. 12.3: fig12_03.cpp
58 // Test drive for stack template
59 #include <iostream.h>
60 #include "tstackl.h"
61
62 int main()
63 {
64 Stack< double > doubleStack( 5 );
65 double f = 1.1;
66 cout << "Pushing elements onto doubleStack\n";
67
68 while ( doubleStack.push( f ) ) { // success true returned
69 cout << f << ' ';
70 f += 1.1;
71 }
72
73 coout << "\nStack is full. cannot push "<< f
74 << "\n\nPopping elements from doubleStack\n";
75
76 while ( doubleStack.pop( f ) ) // success true returned
77 cout << f << ' ';
78
79 cout << "\nStack is empty. Cannot pop\n";
80
81 Stack< int > intStack;
82 int i = 1;
83 cout << "\nPushing elements onto intStack\n";
84
85 while ( intStack.push( i ) ) { // success true returned
86 cout << i << ' ';
87 ++i;
88 }
89
90 cout << "\nStack is full. Cannot push " << i
91 << "\n\nPopping elements from intStack\n";
92
93 while ( intStack.pop( i ) ) // success true returne
94 cout << i << ' ';
95
96 cout << "\nStack is empty. Cannot pop\n";
97 return O;
98 }
输出结果:
Pushing elements onto doubleStack
1.1 2.2 3.3 4.4 5.5
Stack is full. Caunot push 6.6
Pepping elements from doubleStack
5.5 4.4 3.3 2.2 1.1
Stack is empty. Cannot pop
Pushing elements onto intStack
1 2 3 4 5 6 7 8 9 10
Stack is full. Cannot push 11
Popping elements form intStack
10 9 8 7 6 5 4 3 2 1
Stack is empty. Cannot pop
图12.3 演示类模板 Stack
下面建立一个测试堆栈类模板(见图12.5的输出)的驱动程序(函数main)。程序在开始的时候实例化了一个大小为5的对象doublestack。该对象声明为类Stack<double><称为double类型的Stack类)的对象。为了产生出double类型的Stack类的源代码,编译器会自动把模板中的参数类型T替换成double。尽管程序看不到这个源代码,但仍将其放进源代码中编译。
然后程序成功地把1.1、2.2、3.3、4.4和5.5这几个double值压入(push)堆栈doubleStack。当试图将第六个值压人堆栈中的时候,push循环中止(栈已经满了,因为它只能容纳5个元素)。
然后程序再将这5个元素弹出(pop)堆栈(以LIFO顺序)。在试图弹出第六个元素的时,出栈循环中止,因为这时堆栈已经空了。
接下来,程序用下面的声明语句实例化了一个int类型的堆栈intStaek:
Stack<int>intStack
因为没有指定堆栈的大小,所以使用默认构造函数(第11行)中的默认值10作为堆栈的大小。重复上述操作,用循环结构不断向intStaek中压入整数值,直到栈满为止,然后再循环从堆栈中弹出数值,直到栈空为止。
在类模板首部以外的成员函数定义都要以下面的形式开头:
template<class T>
然后,成员函数的定义与普通成员函数的定义相似,只是Stack元素的类型要用类型参数T表示。二元作用域运算符和Stack<T>类模板将成员函数的定义与正确的类模板范围联系起来。本例中,类名是Stack<T>。当建立类型为Stack<double>的对象doubleStack的时候,Stack的构造函数使用new建立了一个表示堆栈的double类型数组。因此,对于语句:
stackPtr = new T [size];
编译器将在模板类Stack<double>中生成下面的代码:
stackPtr new double[size];
注意图12.3函数main中的代码即main上半部分的doubleStack操作和main下半部分的intStaek操作基本相同。这里又可以使用函数模板。图12.4的程序用函数模板testStack进行与图12.3相同的工作,将一系列值压入Stack<T>中并从Stack<T>中弹出数值。函数模板testStack用参数T表示Stack<T>中保存的数据类型。该函数模板取4个参数:Stack<T>类型对象的引用、类型为T的值用作压入Stack<T>的第一个值、类型为T的值用作压入Stack<T>的增量值以及const char*类型的字符串表示输出的Stack<T>对象名。函数main只是实例化Stack<double>类型对象doubleStack
和实例化Stack<int>类型对象intStaek,如下所示(第37行到第38行):
testStack(doubleStack,1.1,1.1,"doubleStack");
teststack(intStack,1,1,"intstack");
注意图12.4的输出与图12.3的输出一致。
1 // Fig. 12.4: fig12_04.cpp
2 // Test driver for Stack template.
3 // Function main uses a function template to manipulate
4 // objects of type Stack< T >.
5 #include <iostream.h>
6 #include "tstack1.h"
7
8 // Function template to manipulate Stack< T >
9 template< class T >
10 void testStack(
11 Stack< T > &theStack, // reference to the Stack< T >
12 T value, // initial value to be pushed
13 T increment, // increment for subsequent values
14 const char *stackName ) // name of the Stack < T > object
15 {
16 cout << "\nPushing elements onto "<< stackName << '\n';
17
18 while ( theStack.push( value ) ) { // success true returned
19 cout << value << ' ';
20 value += increment;
21 }
22
23 cout << "\nStack is full. Cannot push" << value
24 << "\n\nPopping elements from" << stackName << '\n';
25
26 while ( theStack.pop( value ) ) // success true returned
27 cout << value << ' ';
28
29 cout << "\nStack is empty. Cannot pop\n";
3O }
31
32 int main()
33 {
34 Stack< double > doubleStack( 5 );
35 Stack< int > intStack;
36
37 testStack( doubleStack, 1.1, 1.1, "doubleStack" );
30 testStack( intStack, 1, 1, "intStack" );
39
40 return O;
41 }
输出结果:
Pushing elements onto doubleStack
1.2 2.2 3.3 4.4 5.5
Stack is full. Cannot push 6.6
Popping elements from doubleStack
5.5 4.4 3.3 2.2 1.1
Stack is empty. Cannot pop
Pushing elements onto intStack
1 2 3 4 5 6 7 8 9 10
Stack is full. Cannot push 11
Popping elements form intStack
10 9 8 7 6 5 4 3 2 1
Stack is empty. Cannot pop
图 12.4 向函数模板传递Stack模板对象
12.5 类模板与无类型参数
上节的Sstack类模扳只用模板首部的类型参数,也可以使用无类型参数(non-type parameter),无类型参数可以有默认参数,一般将无类型参数当作Const处理。例如,模板首都可以取int elements参数,如下所示:
template<class T,int elements> // note non-type parameter然后下列声明:
Stack<double,100) mostRecentSalesFigures;
实例化(在编译时)100个元素的Stack模板类mostRecentSalesFigures(使用double值)。这个模板类的类型为Stack<double,100>。类的首部可以包含private数据成员,数组声明如下:
T stackHolder[elements]; // array tO hold stack contents
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -