1 该栈只用于存在int型数据
1 #include "../require.h" 2 #include <iostream> 3 4 using namespace std; 5 6 7 class IntStack 8 { 9 enum { ssize = 20 }; 10 int stack[ssize]; 11 int top; 12 13 public: 14 IntStack() : top(0) {} 15 void push(int i) 16 { 17 require(top < ssize, "Too many push()es"); 18 stack[top++] = i; //int型元素,通过赋值运算符,直接存入IntStack栈内部的 int stack[]数组中 19 } 20 21 int pop() 22 { 23 require(top > 0, "Too many pop()s"); 24 return stack[--top]; 25 } 26 27 class iterator; 28 friend class iterator; 29 30 class iterator 31 { 32 IntStack& intStack; 33 int index; 34 35 public: 36 37 iterator(IntStack& is) : intStack(is), index(0) {} 38 39 iterator(IntStack& is, bool) : intStack(is), index(is.top) {} 40 41 // 返回迭代器当前位置的元素 42 int current() const 43 { 44 return intStack.stack[index]; 45 } 46 47 // ++i 48 int operator++() 49 { 50 require(index < intStack.top, "iterator moved out of range"); 51 return intStack.stack[++index]; 52 } 53 54 // i++ 55 int operator++(int) 56 { 57 require(index < intStack.top, "iterator moved out of range"); 58 return intStack.stack[index++]; 59 } 60 61 // i += 2; 62 iterator& operator+=(int amount) 63 { 64 require(index + amount < intStack.top, "IntStack::iterator::operator+=() tried to moved out of bounds"); 65 index += amount; 66 return *this; 67 } 68 69 bool operator==(const iterator& rv) const 70 { 71 return index == rv.index; 72 } 73 74 bool operator!=(const iterator& rv) const 75 { 76 return index != rv.index; 77 } 78 79 friend ostream& operator<<(ostream& os, const iterator& it); 80 }; 81 82 iterator begin() 83 { 84 return iterator(*this); 85 } 86 87 iterator end() 88 { 89 return iterator(*this, true); 90 } 91 }; 92 93 // 重载 << 运算符 -- 全局的 94 ostream& operator<<(ostream& os, const IntStack::iterator& it) 95 { 96 return os << it.current(); 97 } 98 99 100 101 int main() 102 { 103 IntStack stack; 104 for (int i = 0; i < 15; i++) 105 { 106 stack.push(i*3); 107 } 108 109 //---------------------- 110 cout << "Traverse the whole IntStack" << endl; 111 112 IntStack::iterator it = stack.begin(); 113 int n=0; 114 while (it != stack.end()) 115 { 116 cout << n++ << ": " << it++ << endl; 117 } 118 119 120 //---------------------------------- 121 cout << "Traverse a portion of the IntStack" << endl; 122 123 124 IntStack::iterator start = stack.begin(), end2 = stack.end(); 125 start += 2; 126 end2 += 5; //在此,程序退出 127 128 cout << "start = " << start << endl; 129 cout << "end = " << end2 << endl; 130 131 while (start != end2) 132 { 133 cout << start++ << endl; 134 } 135 136 return 0; 137 };
运行结果:
----------------------------------------
附模板化实现(cp406):
容器中放的是值对象,通过重载后的=运算符完成对象数据成员的拷贝(只做了这一层,算是浅拷贝)
StackTemplate.h
1 #ifndef STACKTEMPLATE_H 2 #define STACKTEMPLATE_H 3 4 template<class T> 5 class StackTemplate 6 { 7 enum { ssize = 10 }; 8 9 T stack[ssize]; 10 int top; 11 12 public: 13 StackTemplate() : top(0) {} 14 15 void push(const T& i) 16 { 17 stack[top++] = i; 18 } 19 20 T pop() 21 { 22 return stack[--top]; 23 } 24 25 int size() 26 { 27 return top; 28 } 29 }; 30 #endif
测试文件
1 #include "fibonacci.h" 2 #include "StackTemplate.h" 3 #include <iostream> 4 #include <fstream> 5 #include <string> 6 #include "Book.h" 7 8 using namespace std; 9 10 int main() 11 { 12 13 cout << "---------- StackTemplate<int> ------------------" << endl; 14 StackTemplate<int> intTempl; 15 for (int i = 0; i < 5; i++) 16 { 17 intTempl.push(fibonacci(i)); 18 } 19 for (int k = 0; k < 5; k++) 20 { 21 cout << intTempl.pop() << endl; 22 } 23 24 cout << "---------- StackTemplate<string> ------------------" << endl; 25 26 27 StackTemplate<string> stringTempl; 28 ifstream in("fibonacci.h"); 29 string line; 30 31 while (getline(in, line)) 32 stringTempl.push(line); 33 34 while (stringTempl.size() > 0) 35 cout << stringTempl.pop() << endl; 36 37 38 cout << "---------- StackTemplate<Book> ------------------" << endl; 39 { 40 StackTemplate<Book> books; 41 42 Book bk1("算法精解", "Kyle Loudon", 56.2); 43 Book bk2("Qt程序设计", "Pulat", 10.2); 44 45 books.push(bk1); 46 books.push(bk2); 47 48 } 49 50 return 0; 51 }
运行结果:
从运行结果可以看出,Book bk1("算法精解", "Kyle Loudon", 56.2);拷贝给了books.stack[0](地址,0018fc2c); Book bk2("Qt程序设计", "Pulat", 10.2);拷贝给了books.stack[1](地址,0018fc54)
从调用Book类析构函数的顺序上看,bk2 --> bk1 --> books(books.stack[9] --> books.stack[8] ...... --> books.stack[1] --> books.stack[0])
因为push参数是 const T& i使用的是引用(引用传递),所有元素入栈时没有产生新的Book对象。StackTemplate<Book>完全拥有Book对象,所以超出其作用域后,能够自动析构Book对象。