zoukankan      html  css  js  c++  java
  • 泛型编程拾遗

      首先请大家思考一个问题:以下6个问题可否共享一段代码?

      答案是肯定的。采用泛型编程对问题进行抽象,抽取出以上问题的共性即算法(algorithm)、容器(container)和迭代器(itera),这也是STL(Standard Template Library, 标准模板库)的三要素

     1 template <class Iterator, class Act, class Test>
     2 
     3 void process(Iterator begin, Iterator end, Act act, Test test)
     4 
     5 //对容器中在给定范围内(即起于begin止于end)所有满足给定条件的元素进行处理
     6 
     7 {
     8 
     9     for (; begin != end; ++begin)   //从头至尾遍历容器内的元素
    10 
    11         if (test(*begin))   act(*begin);  //若当前元素满足条件,则对其采取行动
    12 
    13 }

      其中,算法是一系列切实有效的步骤(Act/Test);容器是数据的集合,可以理解为抽象的数组(6个问题中需要遍历的数据集合);迭代器是算法与容器之间的接口,可理解为抽象的指针或游标(迭代器用以访问容器内元素,C++中指针就是一种迭代器)。以上程序中看不到元素的数据类型T,甚至也看不到存放数据的容器container,这是因为元素已经被容器封装,而容器通过迭代器参与算法。

    这么说可能大家不是很理解,下面以第6个问题为例,展示泛型编程的魅力:

     1 //Generic Programming  范型编程 by acelit http://www.cnblogs.com/always-chang/
     2 #include <iostream>
     3 #include <iterator>
     4 using namespace std;
     5 
     6 template <class Iterator, class Act, class Test>
     7 void process(Iterator begin, Iterator end, Act act, Test test)
     8 //对容器中在给定范围内(即起于begin止于end)所有满足给定条件的元素进行处理
     9 {
    10     for (; begin != end; ++begin)   //从头至尾遍历容器内的元素
    11         if (test(*begin))    act(*begin);  //若当前元素满足条件,则对其采取行动
    12 }
    13 //判断是否为非数字字符
    14 bool notDigit(char c)
    15 {
    16     return (c < '0') || (c > '9');
    17 }
    18 //打印非数字字符
    19 void printNondigit(char c)
    20 {
    21     cout << c << "不是数字字符" << endl;
    22 }
    23 
    24 int main()
    25 {
    26     process(istream_iterator<char>(cin), istream_iterator<char>(), printNondigit, notDigit);
    27 
    28     return 0;
    29 }

      问题6中的标准输入也是容器的一种,容器内元素类型为char,template <class Iterator, class Act, class Test>通过模板泛化了容器(还有数组、列表、集合、映射、队列、栈、字符串等),也泛化了元素(可以是任何数据类型),甚至泛化了处理方法和限定条件(迭代器本身就是一种检查容器内元素并遍历元素的数据类型,这种数据类型包含一组确定的操作来遍历、访问容器内的元素,当然遍历方法有很多种了,比如从前往后、从后往前、随机移动…)。

     

      【泛化这个词可以理解为‘隐藏’,这里模板内仅有迭代器的声明,但是迭代器的类型是通过容器来定义的。】

     

      istream_iterator<char>表示元素为char类型的标准输入流(容器)迭代器,()内有标准输入流对象cin表示容器开始位置,为空表示容器结束位置。

     

      怎么样?泛型编程是不是使代码异常简洁,当然付出的代价是理解起来比较抽象了,这里完全看不到I/O读取的过程,也看不到通常的迭代循环,使我们完全摆脱了底层编码的细节,在更高、更抽象的层次上进行编程。

     

      抽象和泛化使代码简洁高效、可重用性大大提高,是泛型编程的“屠龙之技”,也是我们必须掌握的编程技能。

     

      欢迎讨论交流O(∩_∩)O

     

    istream_iterator详见:

    http://www.cplusplus.com/reference/iterator/istream_iterator/

    更多迭代器和容器参考:

    http://www.360doc.com/content/12/1128/13/9290626_250737796.shtml

    本文参考:《冒号课堂——编程范式与OOP思想》

     

     

  • 相关阅读:
    字符串转换相关
    Xcode新功能
    CocoaPods使用详情及版本未更新安装报错
    Cannot create __weak reference in file using manual refs Xcode 7.3
    UIButton实现左文字右图片
    iOS App 上架流程-版本更新注意事项
    iOS App 上架流程-新版本1.0上架
    NSNotification的用法
    NScfBool转bool类型
    百度地图 移动坐标显示该坐标周围对应的信息
  • 原文地址:https://www.cnblogs.com/always-chang/p/6193366.html
Copyright © 2011-2022 走看看