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()
时间: 2024-07-30 20:30:20

Stack的一种简单实现的相关文章

Stack的三种含义【转】

学习编程的时候,经常会看到stack这个词,它的中文名字叫做"栈". 理解这个概念,对于理解程序的运行至关重要.容易混淆的是,这个词其实有三种含义,适用于不同的场合,必须加以区分. 含义一:数据结构 stack的第一种含义是一组数据的存放方式,特点为LIFO,即后进先出(Last in, first out). 在这种数据结构中,数据像积木那样一层层堆起来,后面加入的数据就放在最上层.使用的时候,最上层的数据第一个被用掉,这就叫做"后进先出". 与这种结构配套的,是

java 程序执行输出有两种简单方式

java 程序执行输出有两种简单方式: 1. System.out.println("需要输出的内容"): 该方法可参看运行一个简单的Java程序 结果图: 2. System.out.print("需要输出的内容"): 1 public class HelloWorld 2 { 3 //Java程序的入口方法,程序将从这里开始运行 4 public static void main(String[] args) 5 { 6 //向控制台打印一条语句 7 Syste

两种简单实现菜单高亮显示的JS类(转载)

两种简单实现菜单高亮显示的JS类 近期在写一个博客管理后台的前端,涉及在同一页面两种高亮显示当前菜单的需求.记得当年写静态页时,为了实现高亮都是在每个页面加不同的样式,呵.高亮显示我觉得对于web前端来说,是比较常用到的效果,正好此次又要用到,特地整理出我所写的两种高亮类. 其实思路很简单,第一种方法是通过遍历链接组的href值,通过indexOf判断href值是否被包含在浏览器当前url值中.此方法有一定局限,比如对于iframe内的菜单是不能这样判断的; 第二种方法适用范围更广一样,实现思路

文顶顶 iOS开发UI篇—iOS开发中三种简单的动画设置

iOS开发UI篇—iOS开发中三种简单的动画设置 [在ios开发中,动画是廉价的] 一.首尾式动画 代码示例: // beginAnimations表示此后的代码要“参与到”动画中 [UIView beginAnimations:nil context:nil]; //设置动画时长 [UIView setAnimationDuration:2.0]; self.headImageView.bounds = rect; // commitAnimations,将beginAnimation之后的所

标准库Stack的一种实现

本文实现了STL中stack的大部分功能,同时添加了一些功能. 注意以下几点: 1.Stack是一种适配器,底层以vector.list.deque等实现 2.Stack不含有迭代器 在本例中,我添加了几项功能,包括不同类型stack之间的复制和赋值功能,可以实现诸如Stack<int, vector<int> >和Stack<double, list<double> >之间的复制和赋值,这主要依靠成员函数模板来实现. 为了更方便的实现以上功能,我添加了一个

一种简单实用的全屏方法

实现程序全屏幕显示的思路有很多种,最常见的一种就是: 1)利用Windows API提供的一个结构体WINDOWPLACEMENT来存储全屏显示前视图和主框架窗口在屏幕上的位置和显示信息.非客户区窗口的显隐信息,以便全屏幕显示时恢复窗口原状: 2)通过API函数GetDesktopWindow()得到桌面窗口,由GetWindowRect()得到显示器的尺寸: 3)通过AdjustWindowRect()来计算当客户区大小为屏幕大小时相应的窗口大小: 4)通过SetWindowPlacement

一种简单快速的模板解析方法,活用with javascript版

//一种简单快速的模板解析方法,活用with var parseTpl = function( str, data ) { var tmpl = 'var __p=[];' + 'with(obj||{}){__p.push(\'' + str.replace( /\\/g, '\\\\' ) .replace( /'/g, '\\\'' ) .replace( /<%=([\s\S]+?)%>/g, function( match, code ) { return '\',' + code.

iOS开发UI篇—iOS开发中三种简单的动画设置

iOS开发UI篇—iOS开发中三种简单的动画设置 [在ios开发中,动画是廉价的] 一.首尾式动画 代码示例: // beginAnimations表示此后的代码要“参与到”动画中 [UIView beginAnimations:nil context:nil]; //设置动画时长 [UIView setAnimationDuration:2.0]; self.headImageView.bounds = rect; // commitAnimations,将beginAnimation之后的所

一种简单的软件测试工具——Visual Studio2010

今天,我们来介绍一种简单的软件测试工具——Visual Studio2010.Visual Studio2010是由微软公司研发的一套基于组件的开发工具构成,其中还包括其他一些技术以用于生成功能强大.高性能的应用程序,它重新设计了集成开发环境和代码编辑器,可直接生成代码和文本模板,增强了可视功能以及 WEB 应用程序部署的方法和过程. Visual Studio2010 在功能上有了很大的改进: 1.VisualStudio2010 集成环境进行了改进. 这一点主要体现在,可视增强功能进一步改善