标准库Stack的一种实现
本文实现了STL中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(见上篇文章),用来标示栈空。
详细代码如下:Exception的实现见:借助backtrace和demangle实现异常类Exception
#ifndef STACK_HPP_
#define STACK_HPP_ #include "Exception.h"
#include <deque> //栈空引发的异常
class EmptyStackException : public Exception
{
public:
EmptyStackException() :Exception("read empty stack") { }
}; template <typename T, typename Container = std::deque<T> >
class Stack
{
public:
typedef T value_type;
typedef T& reference;
typedef const T& const_reference;
typedef Container container_type; //容器类型
typedef EmptyStackException exception_type; //异常类型
typedef typename Container::size_type size_type;
typedef Container &container_reference; //容器引用
typedef const Container& const_container_reference; explicit Stack(const container_type &cont = container_type()) :cont_(cont) { }
//不同类型间实现复制
template <typename T2, typename Container2>
Stack<T, Container>(const Stack<T2, Container2> &s);
//不同类型间进行赋值
template <typename T2, typename Container2>
Stack<T, Container> &operator=(const Stack<T2, Container2> &s);
void push(const value_type &val) { cont_.push_back(val); }
void pop()
{
if(cont_.empty())
throw exception_type();
cont_.pop_back();
}
reference top()
{
if(cont_.empty())
throw exception_type();
return cont_.back();
}
const_reference top() const
{
if(cont_.empty())
throw exception_type();
return cont_.back();
}
bool empty() const { return cont_.empty(); }
size_type size() const { return cont_.size(); }
//获取内部容器的引用
const_container_reference get_container() const
{ return cont_; }
friend bool operator==(const Stack &a, const Stack &b)
{
return a.cont_ == b.cont_;
}
friend bool operator!=(const Stack &a, const Stack &b)
{
return a.cont_ != b.cont_;
}
friend bool operator<(const Stack &a, const Stack &b)
{
return a.cont_ < b.cont_;
}
friend bool operator>(const Stack &a, const Stack &b)
{
return a.cont_ > b.cont_;
}
friend bool operator<=(const Stack &a, const Stack &b)
{
return a.cont_ <= b.cont_;
}
friend bool operator>=(const Stack &a, const Stack &b)
{
return a.cont_ >= b.cont_;
}
private:
Container cont_;
};
template <typename T, typename Container>
template <typename T2, typename Container2>
Stack<T, Container>::Stack(const Stack<T2, Container2> &s)
:cont_(s.get_container().begin(), s.get_container().end())
{
}
template <typename T, typename Container>
template <typename T2, typename Container2>
Stack<T, Container> &Stack<T, Container>::operator=(const Stack<T2, Container2> &s)
{
if((void*)this != (void*)&s)
{
cont_.assign(s.get_container().begin(), s.get_container().end());
}
return *this;
}
#endif /* STACK_HPP_ */
测试代码如下:
#include "Stack.hpp"
#include <iostream>
#include <string>
#include <vector>
#include <list>
#include <stdio.h>
using namespace std; int main(int argc, char const *argv[])
{ try
{
Stack<string, vector<string> > st;
st.push("foo");
st.push("bar"); Stack<string, list<string> > st2(st);
//st2 = st; while(!st2.empty())
{
cout << st2.top() << endl;
st2.pop();
} st2.pop(); //引发异常
}
catch (const Exception& ex)
{
fprintf(stderr, "reason: %s\n", ex.what());
fprintf(stderr, "stack trace: %s\n", ex.stackTrace());
} return 0;
}
标准库Stack的一种实现的更多相关文章
- C++ 异常机制分析(C++标准库定义了12种异常,很多大公司的C++编码规范也是明确禁止使用异常的,如google、Qt)
阅读目录 C++异常机制概述 throw 关键字 异常对象 catch 关键字 栈展开.RAII 异常机制与构造函数 异常机制与析构函数 noexcept修饰符与noexcept操作符 异常处理的性能 ...
- 标准库priority_queue的一种实现
优先级队列相对于普通队列,提供了插队功能,每次最先出队的不是最先入队的元素,而是优先级最高的元素. 它的实现采用了标准库提供的heap算法.该系列算法一共提供了四个函数.使用方式如下: 首先,建立一个 ...
- C++标准库(体系结构与内核分析)(侯捷第二讲)
一.OOP和GP的区别(video7) OOP:面向对象编程(Object-Oriented programming) GP:泛化编程(Generic programming) 对于OOP来说,我们要 ...
- C++ 标准库类型-String,Vector and Bitset
<C++ Primer 4th>读书摘要 最重要的标准库类型是 string 和 vector,它们分别定义了大小可变的字符串和集合.这些标准库类型是语言组成部分中更基本的那些数据类型(如 ...
- 关于标准库中的ptr_fun/binary_function/bind1st/bind2nd
http://www.cnblogs.com/shootingstars/archive/2008/11/14/860042.html 以前使用bind1st以及bind2nd很少,后来发现这两个函数 ...
- Python内置模块与标准库
Python内置模块就是标准库(模块)吗?或者说Python的自带string模块是内置模块吗? 答案是:string不是内置模块,它是标准库.也就是说Python内置模块和标准库并不是同一种东西. ...
- Python标准库:1. 介绍
标准库包括了几种不同类型的库. 首先是那些核心语言的数据类型库,比方数字和列表相关的库.在核心语言手冊里仅仅是描写叙述数字和列表的编写方式,以及它的排列,而未定义它的语义. 换一句话说,核心语言手冊仅 ...
- C++标准库类模板(stack)和 队列(queue)
在C++标准库(STL)中有栈和队列的类模板,因此可以直接使用 1.栈(stack):使用栈之前,要先包含头文件 : #include<stack> stack.push(elem); / ...
- 谈谈两种标准库类型---string和vector
两种最重要的标准库---string和vector string和vector是两种最重要的标准库类型,string表示可变长的字符序列,vector存放的是某种给定类型对象的可变长序列. 一.标准库 ...
随机推荐
- 【ZOJ4061】Magic Multiplication(构造)
题意:定义一个新运算为两个数A,B上每一位相乘,然后顺次接在一起,现在给定结果C和原来两个数字的长度,要求恢复成原来的数字A,B 若有多解输出A字典序最小的,A相同输出B字典序最小的,无解输出Impo ...
- Log4Net日志分类和自动维护
背景 在程序中,我们调试运行时信息,Log4Net是一个不错的解决方案.不知道是我用的不好,用到最后反而都不想看日志了.原因是因为我n个功能使用的默认的Logger来记录日志,这样以来,所有功能记录的 ...
- java基础练习 14
import java.util.Scanner; public class Fourtheen { /*打印出所有的"水仙花数",所谓"水仙花数"是指一个三位 ...
- python的ORM框架SQLAlchemy
本节内容 ORM介绍 sqlalchemy安装 sqlalchemy基本使用 多外键关联 多对多关系 表结构设计作业 一.ORM介绍 如果写程序用pymysql和程序交互,那是不是要写原生sql语句 ...
- JAVA SERVLET 属性范围样例
package com.jeelearning.servlet; import java.io.IOException; import javax.servlet.RequestDispatcher; ...
- DotNetCore 笔记
最近公司框架升级到DotNetCore了,但是在用post请求的时候,发现页面的post data后台并没有接收到数据,经过调查发现,netcore用法和之前的MVC5不一样,想要接收post里的da ...
- UVA Live 6437 Power Plant 最小生成树
题意: 有许多油井和村庄什么的,让你使得这些村庄能连通一个油井就好了.第一行给你一个数字T代表有T组测试数据,第二行有 M , N , K ,M代表包括油井在内的村庄数,N 代表有N个 两两连通的地方 ...
- CodeChef February Challenge 2018 Broken Clock (三角函数推导 + 矩阵快速幂)
题目链接 Broken Clock 中文题面链接 令$cos(xα) = f(x)$ 根据三角函数变换公式有 $f(x) = \frac{2d}{l} f(x-1) - f(x-2)$ 我们现在 ...
- (转)Unity3d使用心得(1):ModelImporter的使用、在代码中添加动画片段。
在使用 Unity3d 倒入Fbx模型的时候,动画的动画片段需要自己手动添加模型多了以后会是一个不小的工作量. Unity3d支持 编辑器脚本来控制资源导入的过程.添加一个 AssetPostproc ...
- SimpleDateFormat格式
SimpleDateFormat函数语法: G 年代标志符 y 年 M 月 d 日 h 时 在上午或下午 (1~12) H 时 在一天中 (0~23) m 分 ...