什么是容器适配器
适配器是一种设计模式(设计模式是一套被反复使用的、多数人知晓的、经过分类编目的、代码设计经验的总结),该中模式是将一个类的接口转换成客户希望的另外一个接口。
stack模拟封装
template<class T,class Container = deque<T>>class stack{public:stack(){}void push(const T& data){_con.push_back(data);}void pop(){_con.pop_back();}size_t size()const{return _con.size();}bool empty()const{return _con.empty();}T& top(){return _con.back();}const T& top()const{return _con.back();}private:Container _con;};
queue模拟封装
template<class T , class Container = deque<T>>class queue{public:queue(){}void push(const T& data){_con.push_back(data);}void pop(){_con.pop_front();}T& front(){return _con.front()}const T& front()const{return _con.front()}T& back(){return _con.back();}const T& back()const{return _con.back()}size_t size()const{return _con.size();}bool empty()const{return _con.empty();}private:Container _con;};
- 每种容器都提供了一组接口,如果容器中的接口不能满足需求,那么重新编写容器还是改变我们的需求
- 应该构造一个容器接口到需求接口之间的转换器,称为容器适配器。
- 容器适配器将原容器进行了一层封装,底层基于普通容器,上层对外提供封装后的新接口,满足不同使用者的需求。常用的栈stack、队列deque、优先级队列priority_queue在STL中都有自己的容器适配器。
- 容器适配器对使用者是个黑盒,使用者无需知道容器适配器封装的容器类型,而只需了解容器适配器提供的接口。除了使用STL提供的容器适配器,也可以自己构造容器适配器,将STL中的容器进行封装,对外提供所需的接口。
- 容器适配器可以封装的容器类型根据容器适配器对外提供的接口和容器适配器的内部算法而定。但是任何容器适配器对底层容器都有一些通用的要求,例如,底层容器必须支持添加删除 和访问尾元素操作,因此array不能作为容器适配器的底层容器。
- 栈适配器和队列适配器默认的底层容器是deque,优先队列适配器默认的底层容器是vector。在创建容器适配器的对象时,也可以指定其他合理的容器作为容器适配器的底层容器。创建容器适配器对象的方式如下
栈:stack<int> s;//默认使用dequestack<int,vector<int>> s;//指定使用vector
队列:queue<int> q;//默认使用dequequeue<int,lise<int>> q;//指定使用list优先队列:priority_queue<int> p;//默认使用vectorpriority_queue<int,deque<int>> p;//指定使用dequepriority_queue<int,vector<int>,cmp>> p;//指定使用vector和权重比较函数cmp
注意事项
容器适配器和底层容器是组合的关系,插入容器适配器中的元素最终都保存在底层容器中,容器适配器中的数据成员包括一个用于存储元素的底层容器对象和一些辅助数据。
为什么选择deque作为stack和queue的底层默认容器
stack是一种后进先出的特殊线性数据结构,因此只要具有push_back()和pop_back()操作的线性结构,都可 以作为stack的底层容器,比如vector和list都可以;queue是先进先出的特殊线性数据结构,只要具有 push_back和pop_front操作的线性结构,都可以作为queue的底层容器,比如list。但是STL中对stack和 queue默认选择deque作为其底层容器,主要是因为:
- stack和queue不需要遍历(因此stack和queue没有迭代器),只需要在固定的一端或者两端进行操作。
- 在stack中元素增长时,deque比vector的效率高;queue中的元素增长时,deque不仅效率高,而且内 存使用率高。