Stack的一种简单实现
注意以下几点:
1.Stack是一种适配器,底层以vector、list、deque等实现
2.Stack不含有迭代器
在本例中,我添加了几项功能,包括不同类型stack之间的复制和赋值功能,可以实现诸如Stack<int, vector<int> >和Stack<double, list<double> >之间的复制和赋值,这主要依靠成员函数模板来实现。
为了更方便的实现以上功能,我添加了一个函数:
const_container_reference get_container() const
来获取内部容器的引用。
此外,标准库的stack不检查越界行为,我为stack添加了异常处理,当栈空时,执行pop或者top会抛出异常。这个异常类继承自Exception,用来标示栈空。
代码如下:
1 #ifndef STACK_H 2 #define STACK_H 3 #include "Exception.h" 4 #include <deque> 5 6 class EmptyStackException : public Exception 7 { 8 public: 9 EmptyStackException() 10 :Exception("read empty stack") 11 { } 12 }; 13 14 15 template <typename T, typename Container = std::deque<T> > 16 class Stack 17 { 18 public: 19 typedef T value_type; 20 typedef T& reference; 21 typedef const T& const_reference; 22 typedef Container container_type; 23 typedef EmptyStackException exception_type; 24 typedef typename Container::size_type size_type; 25 typedef Container& container_reference; 26 typedef const Container& const_container_reference; 27 28 explicit Stack(const container_type &cont = container_type()) 29 :_cont(cont) 30 { } 31 32 template <typename T2, typename Container2> 33 Stack<T, Container>(const Stack<T2, Container2> &s); 34 35 template <typename T2, typename Container2> 36 Stack<T, Container> &operator=(const Stack<T2, Container2> &s); 37 38 void push(const value_type &value) { _cont.push_back(value); } 39 40 void pop() 41 { 42 if(_cont.empty()) 43 throw exception_type(); 44 _cont.pop_back(); 45 } 46 47 reference top() 48 { 49 if(_cont.empty()) 50 throw exception_type(); 51 return _cont.back(); 52 } 53 54 const_reference top() const 55 { 56 if(_cont.empty()) 57 throw exception_type(); 58 return _cont.back(); 59 } 60 61 bool empty() const { return _cont.empty(); } 62 size_type size() const { return _cont.size(); } 63 64 const_container_reference get_container() const 65 { return _cont; } 66 67 68 friend bool operator== (const Stack &a, const Stack &b) 69 { return a._cont = b._cont; } 70 71 friend bool operator!= (const Stack &a, const Stack &b) 72 { return !(a == b); } 73 74 friend bool operator< (const Stack &a, const Stack &b) 75 { return a._cont < b._cont; } 76 77 friend bool operator<= (const Stack &a, const Stack &b) 78 { return a._cont <= b._cont; } 79 80 friend bool operator> (const Stack &a, const Stack &b) 81 { return a._cont > b._cont; } 82 83 friend bool operator>= (const Stack &a, const Stack &b) 84 { return a._cont >= b._cont; } 85 86 private: 87 Container _cont; 88 }; 89 90 template <typename T, typename Container> 91 template <typename T2, typename Container2> 92 Stack<T, Container>::Stack(const Stack<T2, Container2> &s) 93 :_cont(s.get_container().begin(), s.get_container().end()) 94 { } 95 96 template <typename T, typename Container> 97 template <typename T2, typename Container2> 98 Stack<T, Container> &Stack<T, Container>::operator=(const Stack<T2, Container2> &s) 99 { 100 if((void *)this != (void *)&s) 101 { 102 _cont.assign(s.get_container.begin(), s.get_container.end()); 103 } 104 105 return *this; 106 } 107 #endif
测试代码如下:
1 #include "stack.h" 2 #include <iostream> 3 #include <string> 4 #include <vector> 5 #include <list> 6 #include <stdio.h> 7 using namespace std; 8 9 int main(int argc, char const *argv[]) 10 { 11 try 12 { 13 Stack<string, vector<string> > s; 14 s.push("foo"); 15 s.push("bar"); 16 17 Stack<string, list<string> > s2(s); 18 while(!s2.empty()) 19 { 20 cout << s2.top() << endl; 21 s2.pop(); 22 } 23 24 s2.pop(); //引发异常 25 } 26 27 catch(const Exception &ex) 28 { 29 fprintf(stderr, "reason : %s\n", ex.what()); 30 fprintf(stderr, "stack trace : %s\n", ex.stackTrace()); 31 } 32 return 0; 33 }
测试结果为:
bar foo reason : read empty stack stack trace : ./a.out() ./a.out() ./a.out() ./a.out() ./a.out() /lib/libc.so.6(__libc_start_main+0xe6) ./a.out()