[STL]源码解析:stack

我们在使用STL时,包含的头文件是<stack.h>,而stack中并没有实体,只是“简单”包含了<_stack.h>,真正的东西,在这个头文件中。

一、stack的三种模板

#if !defined ( _STLP_LIMITED_DEFAULT_TEMPLATES )
template <class _Tp, class _Sequence = deque<_Tp> >
#elif defined ( _STLP_MINIMUM_DEFAULT_TEMPLATE_PARAMS )
#  define _STLP_STACK_ARGS _Tp
template <class _Tp>
#else
template <class _Tp, class _Sequence>
#endif
stack模板类有三种模板。一般情况下我们不会定义_STLP_LIMITED_DEFAULT_TEMPLATES(如果定义了则表示不使用默认模板),默认模板是:

template <class _Tp, class _Sequence = deque<_Tp> >
可见,stack的内部实现实际上是使用deque(双端队列)。

二、起别名

#ifdef _STLP_STACK_ARGS
  typedef deque<_Tp> _Sequence;
  typedef stack<_Tp> _Self;
#else
  typedef stack<_Tp, _Sequence> _Self;
#endif
根据情况_Self。

  typedef typename _Sequence::value_type      value_type;
  typedef typename _Sequence::size_type       size_type;
  typedef          _Sequence                  container_type;

  typedef typename _Sequence::reference       reference;
  typedef typename _Sequence::const_reference const_reference;
由此可见,_Suquence必须有如下成员(例如Deque就有此四个成员):

value_type;

size_type;

reference;

const_reference。

三、成员变量

  _Sequence c;
只有一个成员变量,来记录容器的元素。这里仍是deque。

四、栈的方法

1. 判断栈是否为空

bool empty() const { return c.empty(); }
2. 栈的大小

size_type size() const { return c.size(); }

3. 访问栈顶元素

  reference top() { return c.back(); }
  const_reference top() const { return c.back(); }
4. 出栈

void pop() { c.pop_back(); }
5. 入栈

 void push(const value_type& __x) { c.push_back(__x); }
6. 得到整个内部容器,即得到双向队列(并非栈的必须方法)

const _Sequence& _Get_s() const { return c; }
7. 交换两个栈的内部容器(并非栈的必须方法)

#if defined (_STLP_USE_PARTIAL_SPEC_WORKAROUND) && !defined (_STLP_FUNCTION_TMPL_PARTIAL_ORDER)
  void _M_swap_workaround(_Self& __x) {
    _Sequence __tmp = c;
    c = __x.c;
    __x.c = __tmp;
  }
#endif
五、重载操作符(针对栈的)

1. 定义“方便”宏

#ifndef _STLP_STACK_ARGS
#  define _STLP_STACK_ARGS _Tp, _Sequence
#  define _STLP_STACK_HEADER_ARGS class _Tp, class _Sequence
#else
#  define _STLP_STACK_HEADER_ARGS class _Tp
#endif
2. 重载<操作符

template < _STLP_STACK_HEADER_ARGS >
inline bool _STLP_CALL  operator<(const stack< _STLP_STACK_ARGS >& __x,
                                  const stack< _STLP_STACK_ARGS >& __y)
{ return __x._Get_s() < __y._Get_s(); }
注意几点(此后不再说明):

(1) 声明为inline。因为函数较短,适用(内联会在任何被调用的地方展开);

(2) 参数声明为常量引用。因为传入的参数可能很大,如果普通传参会复制个副本,浪费内存。

3. 重载==操作符

template < _STLP_STACK_HEADER_ARGS >
inline bool _STLP_CALL  operator==(const stack< _STLP_STACK_ARGS >& __x,
                                   const stack< _STLP_STACK_ARGS >& __y)
{ return __x._Get_s() == __y._Get_s(); }

比较操作符都依赖于Sequence(即deque)的比较操作符。

六、综上所述,stack实际上并没有多少自已的逻辑,几乎完全依赖于deque。在实现上,好像也可能用stack作为deque的子类来实现,为什么不这样而采用模板的形式呢?可能是因为,deque还提供了许多stack并不需要的方法,这违背面向对象的原则,stack并非是deque的子类(没有deque的全部特性)。


1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看REaDME.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。
1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 、资源1项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值