zoukankan      html  css  js  c++  java
  • 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
    ", ex.what());
    30         fprintf(stderr, "stack trace : %s
    ", 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()
  • 相关阅读:
    WordPress Export To Text插件‘download’参数远程文件包含漏洞
    WordPress EELV Newsletter插件跨站脚本漏洞
    WordPress Exploit Scanner插件安全绕过漏洞
    WordPress Feedweb插件跨站脚本漏洞
    WordPress User Role Editor插件跨站请求伪造漏洞
    Apache Struts ‘includeParams’安全绕过漏洞
    Linux Kernel ‘tcp_collapse()’ 本地拒绝服务漏洞
    Linux Kernel "iscsi_add_notunderstood_response()"缓冲区溢出漏洞
    开始读《Agile Web Development with Rails》
    开始使用2个显示器
  • 原文地址:https://www.cnblogs.com/gjn135120/p/4007283.html
Copyright © 2011-2022 走看看