STL源码分析之配接器

前言

本节分析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_functionbinary_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.hstl_iterator.h文件里面还有很多函数, 有兴趣可以好好看看, 这里也只是简单的分析. 源码面前没有秘密.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
对于C++ STL源码分析,这是一个广泛而复杂的话题。C++ STL是C++标准库中的一部分,包含了许多不同的容器、算法和迭代器等组件,用于提供通用的数据结构和算法支持。 在进行源码分析之前,你需要具备一定的C++编程知识和理解C++模板的工作原理。然后,你可以通过查看STL源码实现来深入了解其内部机制。 在C++ 11中,STL引入了一些新的特性和容器。例如,引用中提到的range-based for循环语句,可以更方便地遍历容器中的元素。此外,C++ 11还对容器进行了分类,包括序列容器、关联容器和无序容器等。 引用提到了STL的六个主要部分,包括容器、算法、迭代器、函数对象、适器和分器。这些部分提供了不同的功能和特性,可以满足各种编程需求。 在C++ 11中,一些容器名称发生了变化,如slist被重命名为forward_list,hash_set和hash_map被重命名为unordered_set和unordered_map。这些变化是为了更好地反映容器的功能和语义。 要深入了解STL源码,你可以参考一些重要的资源网站,如cplusplus.com、cppreference.com和gcc.gnu.org。这些网站提供了详细的文档和例子,以帮助你理解STL的实现细节。 总之,要进行C++ STL源码分析,你需要具备一定的编程和模板知识,并参考相关的文档和资源。通过深入研究STL源码实现,你将能够更好地理解其内部机制和使用方法。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值