模板类 stack 的理解 积累

来源:互联网 发布:灵界室友网络剧下载 编辑:程序博客网 时间:2024/05/21 17:33

template<class T, class Container = deque<T> > class stack;

参数:

T:元素类型

Container:用于存储和访问元素的底层容器类型。

  

STL学习之stack适配器



LIFO stack

stack是一个容器适配器类型,它被设计成LIFO(最后一个进入栈的,第一个出),并且元素的插入和提取操作只能在容器的尾部。

stack作为容器适配器, 用一个具体的容器类的封装对象作为其底层容器,提供一个具体的访问容器元素的成员函数集合。元素都是从具体的容器的“尾部”进行推送(push)和拉出(pop)操作,这个“尾部”就是所谓的栈顶(top)。

底层容器可以是任何的标准容器类模板或者其他的具体的设计容器类。仅有的要求是需要支持下面的操作:

  • back()
  • push_back()
  • pop_back()

因此可以使用vector,deque和list这样标准容器类模板。默认的,如果对一个特殊的栈类没有指定容器类,使用deque标准类模板。

在c++标准的模板类的定义中,stack是有两个模板参赛的模板:

template<class T, class Container = deque<T> > class stack;

参数:

T:元素类型

Container:用于存储和访问元素的底层容器类型。

stack::stack

[cpp] view plaincopy
  1. explicit stack( const Container& ctnr = Container() );  

栈的构造函数

构造一个栈容器适配器对象。

一个容器适配器保持容器对象为数据。如果有容器对象,这个对象是传递给构造函数参数的一个拷贝,否则,是一个空的容器。

参数:

cntr

      容器对象。

     Container是第二个类模板参数(stack的底层容器的类型,默认为deque<T>)。

实例:

[cpp] view plaincopy
  1. #include <iostream>  
  2. #include <vector>  
  3. #include <deque>  
  4. #include <stack>  
  5.   
  6. using namespace std;  
  7.   
  8. int main(void)  
  9. {  
  10.   deque<int> mydeque(2, 100);  
  11.   vector<int> myvector(3, 200);  
  12.     
  13.   stack<int> first;  
  14.   stack<int> second(mydeque);  
  15.     
  16.   stack<int, vector<int> > third;  
  17.   stack<int, vector<int> > fourth(myvector);  
  18.   
  19.   cout << "size of first: " << first.size() << endl;  
  20.   cout << "size of second: " << second.size() << endl;  
  21.   cout << "size of third:" << third.size() << endl;  
  22.   cout << "size of fourth: " << fourth.size() << endl;  
  23.   
  24.   return 0;  
  25. }  
执行结果:

liujl@liujl-Rev-1-0:~/mycode/STL$ ./stack 
size of first: 0
size of second: 2
size of third:0
size of fourth: 3

stack::empty

bool empty() const;

测试容器是否为空

返回是否栈为空,例如,size是否为0。

这个成员函数实际上调用的是同名的底层容器对象的成员函数。

实例:

[cpp] view plaincopy
  1. #include <iostream>  
  2. #include <stack>  
  3.   
  4. using namespace std;  
  5.   
  6. int main(void)  
  7. {  
  8.    stack<int> mystack;  
  9.    int sum(0);  
  10.      
  11.    for (int i=1; i<=10; i++)  
  12.       mystack.push(i);  
  13.   
  14.    while(!mystack.empty())  
  15.     {  
  16.        sum += mystack.top();  
  17.        mystack.pop();  
  18.     }  
  19.    cout << "total: " << sum << endl;  
  20.      
  21.    return 0;  
  22. }  
执行结果:

liujl@liujl-Rev-1-0:~/mycode/STL$ ./stack_empty 
total: 55

stack::push

void push( const T& x);

增加元素

在栈顶增加一个心的元素,在现在的栈顶元素之上。新的元素内容初始化为x的一个拷贝。

这个成员函数实际上调用底层容器对象的push_back成员函数。

参数

x

      需要拷贝给新元素的值。

      T是第一个模板参数(栈中存储的元素类型)

stack::pop

void pop();

移除元素。

移除栈顶的元素,实际上size减1。在弹出之前调用stack::top成员函数,可以获得此元素值。

这个成员函数实际上调用底层容器对象的pop_back函数(例如deque::pop_back)。

push/pop实例:

[cpp] view plaincopy
  1. #include <iostream>  
  2. #include <stack>  
  3.   
  4. using namespace std;  
  5.   
  6. int main(void)  
  7. {  
  8.   stack<int> mystack;  
  9.     
  10.   for (int i=0; i<5; i++)  
  11.      mystack.push(i);  
  12.     
  13.   cout << "Pop up elements: "<< endl;  
  14.   while (!mystack.empty())  
  15.   {  
  16.      cout << "  "<<mystack.top();  
  17.      mystack.pop();  
  18.   }  
  19.   cout << endl;  
  20.   return 0;  
  21. }  
执行结果:

liujl@liujl-Rev-1-0:~/mycode/STL$ ./stack_pop_push 
Pop up elements: 
  4  3  2  1  0

stack::size

size_type size() const;

返回在栈中的元素个数。

stack::top

value_type& top();

const value_type& top() const;

访问下一个元素

返回栈中下一个元素的引用。由于栈是LIFO容器,所以此元素是栈中最后一个push进去的元素。


附件(stl_stack.h中stack类定义)

[cpp] view plaincopy
  1. #ifndef __SGI_STL_INTERNAL_STACK_H  
  2. #define __SGI_STL_INTERNAL_STACK_H  
  3.   
  4. #include <sequence_concepts.h>  
  5.   
  6. __STL_BEGIN_NAMESPACE  
  7.   
  8. // Forward declarations of operators == and <, needed for friend declaration.  
  9.   
  10. template <class _Tp,   
  11.           class _Sequence __STL_DEPENDENT_DEFAULT_TMPL(deque<_Tp>) >  
  12. class stack;  
  13.   
  14. template <class _Tp, class _Seq>  
  15. bool operator==(const stack<_Tp,_Seq>& __x, const stack<_Tp,_Seq>& __y);  
  16.   
  17. template <class _Tp, class _Seq>  
  18. bool operator<(const stack<_Tp,_Seq>& __x, const stack<_Tp,_Seq>& __y);  
  19.   
  20.   
  21. template <class _Tp, class _Sequence>  
  22. class stack {  
  23.   
  24.   // requirements:  
  25.   
  26.   __STL_CLASS_REQUIRES(_Tp, _Assignable);  
  27.   __STL_CLASS_REQUIRES(_Sequence, _BackInsertionSequence);  
  28.   typedef typename _Sequence::value_type _Sequence_value_type;  
  29.   __STL_CLASS_REQUIRES_SAME_TYPE(_Tp, _Sequence_value_type);  
  30.   
  31.   
  32. #ifdef __STL_MEMBER_TEMPLATES  
  33.   template <class _Tp1, class _Seq1>  
  34.   friend bool operator== (const stack<_Tp1, _Seq1>&,  
  35.                           const stack<_Tp1, _Seq1>&);  
  36.   template <class _Tp1, class _Seq1>  
  37.   friend bool operator< (const stack<_Tp1, _Seq1>&,  
  38.                          const stack<_Tp1, _Seq1>&);  
  39. #else /* __STL_MEMBER_TEMPLATES */  
  40.   friend bool __STD_QUALIFIER  
  41.   operator== __STL_NULL_TMPL_ARGS (const stack&, const stack&);  
  42.   friend bool __STD_QUALIFIER  
  43.   operator< __STL_NULL_TMPL_ARGS (const stack&, const stack&);  
  44. #endif /* __STL_MEMBER_TEMPLATES */  
  45.   
  46. public:  
  47.   typedef typename _Sequence::value_type      value_type;  
  48.   typedef typename _Sequence::size_type       size_type;  
  49.   typedef          _Sequence                  container_type;  
  50.   
  51.   typedef typename _Sequence::reference       reference;  
  52.   typedef typename _Sequence::const_reference const_reference;  
  53. protected:  
  54.   _Sequence c;  
  55. public:  
  56.   stack() : c() {}  
  57.   explicit stack(const _Sequence& __s) : c(__s) {}  
  58.   
  59.   bool empty() const { return c.empty(); }  
  60.   size_type size() const { return c.size(); }  
  61.   reference top() { return c.back(); }  
  62.   const_reference top() const { return c.back(); }  
  63.   void push(const value_type& __x) { c.push_back(__x); }  
  64.   void pop() { c.pop_back(); }  
  65. };  
  66.   
  67. template <class _Tp, class _Seq>  
  68. bool operator==(const stack<_Tp,_Seq>& __x, const stack<_Tp,_Seq>& __y)  
  69. {  
  70.   return __x.c == __y.c;  
  71. }  
  72.   
  73. template <class _Tp, class _Seq>  
  74. bool operator<(const stack<_Tp,_Seq>& __x, const stack<_Tp,_Seq>& __y)  
  75. {  
  76.   return __x.c < __y.c;  
  77. }  
  78.   
  79. #ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER  
  80.   
  81. template <class _Tp, class _Seq>  
  82. bool operator!=(const stack<_Tp,_Seq>& __x, const stack<_Tp,_Seq>& __y)  
  83. {  
  84.   return !(__x == __y);  
  85. }  
  86.   
  87. template <class _Tp, class _Seq>  
  88. bool operator>(const stack<_Tp,_Seq>& __x, const stack<_Tp,_Seq>& __y)  
  89. {  
  90.   return __y < __x;  
  91. }  
  92.   
  93. template <class _Tp, class _Seq>  
  94. bool operator<=(const stack<_Tp,_Seq>& __x, const stack<_Tp,_Seq>& __y)  
  95. {  
  96.   return !(__y < __x);  
  97. }  
  98.   
  99. template <class _Tp, class _Seq>  
  100. bool operator>=(const stack<_Tp,_Seq>& __x, const stack<_Tp,_Seq>& __y)  
  101. {  
  102.   return !(__x < __y);  
  103. }  
  104.   
  105. #endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */  
  106.   
  107. __STL_END_NAMESPACE  
  108.   
  109. #endif /* __SGI_STL_INTERNAL_STACK_H */  





  

STL源码剖析1

分类: STL/BOOST 13人阅读 评论(0) 收藏 举报

stl概论

stl以抽象概念为主题而非以实际类为主的结构,形成了一个严谨的接口标准。在此接口之下,任何组件都有最大的独立性,并以所谓迭代器胶合起来,或以所谓配接器互相配接,或以所谓仿函数动态选择某种策略。

C++允许我们自行定义型别,C++template允许我们将型别参数化,藉由两者结合并透过traits变成技法形成STL。

stl六大组件:containers,algorithms,iterators,functors,adapters,allocators。

template<class T, class Sequence = deque<T> >

class stack

{

     // friend bool operator == <T> (const stack<T>&, const stack<T>&); // OK

    // friend bool operator == <T> (const stack&, const stack&);                // OK

      friend bool operator == <> (const stack&, const stack&);                   // OK

     friend bool operator  < <> (const stack&, const stack&);   //<> 不理解不理解啊

    // friend bool operator == (const stack&, const stack&);                        // error

};

..... // 实现省略

这种奇特的语法是为了实现所谓的 bound friend templates,也就是所说 class template 的某个具体实现与friend function template的某个具现体有一对一的关系。

int main()

{

     stack<int> x;

     stack<int> y;

      cout << (x == y) << endl; // OK

     stack<char> y1;

     cout << (x == y1) << endl;  // error

}

解答:(侯捷:STL组态解释部分p32)

组态: __STL_NULL_TMPL_ARGS (bound friend template friend)

定义如下 为 <>

就是所谓的class template 的某个具现体(instantiation)与其friend function template 的某个具现体有一对一的关系。

0 0
原创粉丝点击