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()

 

posted @ 2014-10-05 18:49  (@_@)ゞ  阅读(229)  评论(0编辑  收藏  举报