c++中queue的實現
阿新 • • 發佈:2019-01-04
本文實現了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(見上篇文章),用來標示棧空。
#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; }