什么是 STL 适配器,怎么用
扫描二维码
随时随地手机看文章
STL适配器,所谓适配器在设计模式中也有相应的讲解即,在不改变原有接口的前提下,将该接口转换为我们期待的接口,通常要求的接口和被适配的接口会有相同或者相似的功能,分为三者,Target(客户要求的接口) adaptee:(原有的接口,被适配的接口) adapter(适配器接口),adapter是共有继承了Target,成员变量获得adaptee的指针来实现的!!!
,适配器模式,分为两种一种是对象适配器模式,一种是类适配器模式,STL适配器有三种,一种是迭代器适配器,一种是函数适配器,最后一种则是容器适配器:
所谓适配器说的简单些,其根本就是类型转换器其较简单的讲解就是原本是向前的操作,转换之后变成了向后的操作。我们采用原本是iterator适配器,我们从容器中从前向后进行遍历,而反向迭代器则是从最后元素开始遍历,其下一个则是向前移动的。我们将原有的迭代器进行封装,其C++代码如下:
templateclass TVector_iterator; templateclass Iterator_m { public: virtual T*First() = 0; virtual T*Next() = 0; virtual bool isDone() = 0; }; templateclass TVector { private: T* m_list; int m_cur_num; int m_max_num; public: TVector() { m_list = NULL; m_max_num = 24; m_list = new T[m_max_num]; m_cur_num = 0; } int get_num() { return m_cur_num; } T* First() { return m_list; } TVector_iterator* create_iterator() { return new TVector_iterator(this); } void append(T m) { if (m_cur_num == m_max_num) { T* new_list = new T[m_max_num * 2]; for (int i = 0; i < m_max_num; i++) { new_list[i] = m_list[i]; } delete m_list; m_list = new_list; } m_list[m_cur_num++] = m; } }; templateclass TVector_iterator :public Iterator_m{ private : TVector* m_hinstance; int m_cur_pos; T* m_head; public: TVector_iterator(TVector* m) { m_hinstance = m; m_cur_pos = 0; m_head = m_hinstance->First(); } T* First() { m_cur_pos = 0; return m_head=m_hinstance->First(); } T* Next() { return &m_head[m_cur_pos++]; } T* Prev() { return &m_head[m_cur_pos--]; } T* Last() { m_cur_pos = m_hinstance->get_num() - 1; m_head = m_hinstance->First(); return &m_head[m_cur_pos]; } int get_cur_pos() { return m_cur_pos; } bool isDone() { if (m_cur_pos == m_hinstance->get_num()) { return true; } return false; } }; templateclass reverse_iterator_m :public Iterator_m{ private: TVector_iterator* m_iterator; public: T* First() { return m_iterator->Last(); } T* Next() { return m_iterator->Prev(); } reverse_iterator_m(TVector_iterator* m) { m_iterator = m; m_iterator->First(); } bool isDone() { if (m_iterator->get_cur_pos() == -1) { return true; } return false; } }; int main() { TVectormm; for (int i = 0; i < 20; i++) { mm.append(i); } TVector_iterator* itr = mm.create_iterator(); cout << "这是使用Iterator 的结果n"; while (!itr->isDone()) { cout << *(itr->Next()) << endl; } reverse_iterator_m* ritr = new reverse_iterator_m(itr); cout << "这是使用reverse_Iterator 的结果n"; ritr->First(); while (!ritr->isDone()) { cout << *(ritr->Next()) << endl; } }
接下来要讨论的就是函数适配器,所谓函数适配器,也即函数的类型转换,比如大家最常用的例子是find_if,find_if的第三个参数是需要接受一个一元函数,然而我们真的需要的是动态获取find_if中的first到last中的数据,另一个参数则是确定的值,这时候,就会需要进行函数的转换,也即函数适配器:其C++代码实现下所示:
#include#includeusing namespace std; templatestruct get_equal :public binary_function{ bool operator()(T m, T n) { return m == n; } }; templateclass bind_1St_cla :public unary_function{ protected: Fn op;//保存函数对象 typename Fn::first_argument_type value;//根据函数第一参数的类型,声明变量,将值保存,以后不变,也即进行了绑定 public: //这里面需要做的两个,一个是构造函数,对op 和value进行赋值 bind_1St_cla(const Fn& m, typename Fn::first_argument_type n) :op(m), value(n) {} //第二个是重载()操作符 typename Fn::result_type operator()(const typename Fn::second_argument_type m) { return op(value, m); } }; //接下来是定义一个内联函数,对类bind_1St_cla进行使用 templateinline /*标志常驻内存,提高速度*/ bind_1St_clathe_real_fuction(const Fn& m, const Ty ha) { return bind_1St_cla(m, ha); } int main() { int a[] = { 1, 2, 3, 4, 5, 6, 7, 8 }; int* mm = find_if(a, a + 8, the_real_fuction(get_equal(), 4)); cout << *mm << endl; }