STL原始碼剖析——stack
阿新 • • 發佈:2019-01-02
stack容器配接器
stack是一種“先進後出”的資料結構,它只能在棧頂對資料進行操作,即只能在棧頂進行新增元素、移除元素、取得最頂端元素。不能進行遍歷行為,所以不需要設計自己的迭代器。在SGI STL的原始碼<stl_stack.h>的設計中,它是基於某種容器作為底部結構的,預設容器是deque容器,使用者也可以自己指定容器的型別。
由於原始碼比較短,同時是基於其他容器進行操作的,這裡只給出原始碼的剖析:
stl_stack.h // Filename: stl_stack.h #ifndef __SGI_STL_INTERNAL_STACK_H #define __SGI_STL_INTERNAL_STACK_H __STL_BEGIN_NAMESPACE // 如果編譯器不能根據前面模板引數推匯出後面使用的預設引數型別, // 那麼就需要手工指定, 本實作stack內部容器預設使用deque // 選用deque可以在儲存空間不足時可以動態增加, 而且代價很低 #ifndef __STL_LIMITED_DEFAULT_TEMPLATES template <class T, class Sequence = deque<T> > #else template <class T, class Sequence> #endif class stack { // 特化的全域性運算子, 提供operator==和<過載則構建出所有運算子 // 其具體細節見<stl_pair.h>中的說明 friend bool operator== __STL_NULL_TMPL_ARGS (const stack&, const stack&); friend bool operator< __STL_NULL_TMPL_ARGS (const stack&, const stack&); public: // 由於stack僅支援對棧頂元素的操作, 所以不定義STL要求的 // pointer, iterator, difference_type typedef typename Sequence::value_type value_type; typedef typename Sequence::size_type size_type; typedef typename Sequence::reference reference; typedef typename Sequence::const_reference const_reference; protected: Sequence c; // 這個是我們實際維護的容器 public: // 下面的操作完全使用內部容器的成員函式實現 // 這再次體現了STL高度的可複用性:-) // 判斷stack是否為空 bool empty() const { return c.empty(); } // stack中元素個數 size_type size() const { return c.size(); } // 返回棧頂元素, 注意這裡返回的是引用!!! reference top() { return c.back(); } const_reference top() const { return c.back(); } // 在棧頂追加新元素 void push(const value_type& x) { c.push_back(x); } // 移除棧頂元素, 注意不返回元素的引用, // 很多初學者隨機用此容器時經常誤認為pop()操作同時會返回棧頂元素的引用 void pop() { c.pop_back(); } }; // 判斷兩個stack是否相等, 就要測試其內部維護容器是否相等 // x.c == y.c會呼叫容器過載的operator == template <class T, class Sequence> bool operator==(const stack<T, Sequence>& x, const stack<T, Sequence>& y) { return x.c == y.c; } template <class T, class Sequence> bool operator<(const stack<T, Sequence>& x, const stack<T, Sequence>& y) { return x.c < y.c; } __STL_END_NAMESPACE #endif /* __SGI_STL_INTERNAL_STACK_H */ // Local Variables: // mode:C++ // End:
例項:
// constructing stacks #include <iostream> // std::cout #include <stack> // std::stack #include <vector> // std::vector #include <deque> // std::deque int main () { std::deque<int> mydeque (3,100); // deque with 3 elements std::vector<int> myvector (2,200); // vector with 2 elements std::stack<int> first; // empty stack std::stack<int> second (mydeque); // stack initialized to copy of deque std::stack<int,std::vector<int> > third; // empty stack using vector std::stack<int,std::vector<int> > fourth (myvector); std::cout << "size of first: " << first.size() << '\n'; std::cout << "size of second: " << second.size() << '\n'; std::cout << "size of third: " << third.size() << '\n'; std::cout << "size of fourth: " << fourth.size() << '\n'; second.push(2); std::cout << "The element at the top of stack second is: " << second.top( ) << "." << std::endl; std::cout << "size of second: " << second.size() << '\n'; return 0; } Output: size of first: 0 size of second: 3 size of third: 0 size of fourth: 2 The element at the top of stack second is:2 . size of second: 4