前言
本节分析STL组件之一的配接器, 配接器就像转接口一样, 将一个对class封装变成了另外一个功能的class, 这在前面分析容器的时候遇到过, 比如: map, set等, 都是修改底层接口形成另外一个功能的class.
配接器可以应用于 : 仿函数, 迭代器, 容器.
关于配接器应用于容器前面都分析过了, 接下来就分析部分应用于仿函数和迭代器的配接器吧.
应用于迭代器
STL实现了很多应用于迭代器上的配接器, 比如 : reverse iterators
,iostream iterators
等, 这里就选择前两个进行分析
reverse iterators
template <class Iterator>
class reverse_iterator
{
protected:
Iterator current;
public:
// 反向迭代器的5种相应型别和正向的正向迭代器相同
typedef typename iterator_traits<Iterator>::iterator_category iterator_category;
typedef typename iterator_traits<Iterator>::value_type value_type;
typedef typename iterator_traits<Iterator>::difference_type difference_type;
typedef typename iterator_traits<Iterator>::pointer pointer;
typedef typename iterator_traits<Iterator>::reference reference;
// 正向迭代器
typedef Iterator iterator_type;
// 反向迭代器
typedef reverse_iterator<Iterator> self;
public:
// 构造函数
reverse_iterator() {}
// 将反向迭代器与某种迭代器联系起来
explicit reverse_iterator(iterator_type x) : current(x) {}
reverse_iterator(const self& x) : current(x.current) {}
// 返回正向迭代器
iterator_type base() const { return current; }
// 反向迭代器取值时,先将正向迭代器后退一位,再取值
reference operator*() const {
Iterator tmp = current;
return *--tmp;
}
// 反转后end变成了begin. begin变成了end
// 注意一点就是end是指向最后一个元素的后一个位置
self& operator++() {
--current;
return *this;
}
self operator++(int) {
self tmp = *this;
--current;
return tmp;
}
self& operator--() {
++current;
return *this;
}
self operator--(int) {
self tmp = *this;
++current;
return tmp;
}
// 前进和后退方向相反
self operator+(difference_type n) const {
return self(current - n);
}
self& operator+=(difference_type n) {
current -= n;
return *this;
}
self operator-(difference_type n) const {
return self(current + n);
}
self& operator-=(difference_type n) {
current += n;
return *this;
}
reference operator[](difference_type n) const { return *(*this + n); }
};
iostream iterators
template <class T, class Distance = ptrdiff_t>
class istream_iterator {
// 定义友元
friend bool
operator== __STL_NULL_TMPL_ARGS (const istream_iterator<T, Distance>& x,
const istream_iterator<T, Distance>& y);
protected:
istream* stream; // 定义istream指针
T value;
bool end_marker;
// 执行读
void read() {
end_marker = (*stream) ? true : false;
// 当有数据等待就进行读操作
if (end_marker) *stream >> value;
// 当读取到不符合型别或者eof时返回false, 不再读取
end_marker = (*stream) ? true : false;
}
public:
// 类型定义, 满足traits编程
typedef input_iterator_tag iterator_category;
typedef T value_type;
typedef Distance difference_type;
typedef const T* pointer;
typedef const T& reference;
istream_iterator() : stream(&cin), end_marker(false) {} // 默认传入cin指针
istream_iterator(istream& s) : stream(&s) { read(); }
reference operator*() const { return value; }
#ifndef __SGI_STL_NO_ARROW_OPERATOR
pointer operator->() const { return &(operator*()); }
#endif /* __SGI_STL_NO_ARROW_OPERATOR */
// 这里迭代器++表示将要读取到下一个数据
istream_iterator<T, Distance>& operator++() {
read();
return *this;
}
istream_iterator<T, Distance> operator++(int) {
istream_iterator<T, Distance> tmp = *this;
read();
return tmp;
}
};
应用于仿函数
要实现仿函数可配接就需要继承unary_function
或binary_function
.
上一节仿函数所分析的"函数"都可用于配接.
template <class Operation, class T>
inline binder1st<Operation> bind1st(const Operation& op, const T& x) {
typedef typename Operation::first_argument_type arg1_type;
return binder1st<Operation>(op, arg1_type(x));
}
总结
本节对STL的配接器的部分函数进行了分析, stl_function.h
和stl_iterator.h
文件里面还有很多函数, 有兴趣可以好好看看, 这里也只是简单的分析. 源码面前没有秘密.