C++ STL与泛型编程-第二篇

C++ STL与泛型编程-第二篇 (Boolan)

本章内容:
1 OOP(面向对象编程) vs. GP(泛型编程)
2 模板(泛化,全特化,偏特化)
3 分配器
4 容器之间实现关系与分类
5 深度探索list
6 迭代器的设计原理和interator traits的作用与设计


1 OOP(面向对象编程) vs. GP(泛型编程)

  • OOP企图将datas和methods关联在一起。
    list不能使用全局的::sort()进行排序,因为全局sort()中用到了RandomAccessIterator,而list没有该迭代器,只有当有RandomAccessIterator时才能进行全局的排序操作。

  • GP却是将datas和methods分开来。
    Data Structures(Containers)
    template<class T, class Alloc=alloc>
    class vector{
    ……
    };
    template<class T, class Alloc=alloc, size_t BufSiz=0>
    class deque{
    ……
    };
    Alogrithms
    template<typename _RandomAccessIterator>
    inline void
    sort(_RandomAccessIterator __first,
    _RandomAccessIterator __last)
    {
    ……
    }

      template<typename _RandomAccessIterator,
                      typename _Compare>
      inline void
      sort(_RandomAccessIterator __first,
            _RandomAccessIterator __last,
            _Compare __comp)
      {
        ……
      }
    
  • 采用GP:
    (1). ContainersAlgorithms团队可各自闭门造车,其间以iterator贯通即可。
    (2). AlgorithmsIterators确定操作范围,并通过Iterators取用Container元素。

  • 结构说明图如下所示:


    GP采用结构
  • 代码示例如下所示:


    GP示例程序

2 模板(泛化,全特化,偏特化)

  • Class Templates类模板:
    template<typename T>
    class complex
    {
    public:
    Complex(T r = 0, T i = 0):re(r), im(i) { }
    T real() const { return re; }
    T imag() const { return im; }
    private:
    T re, im;
    friend Complex& __doapl(complex*, const complex&);
    };

  • 模板类使用

      {
              complex<double> c1(2.5, 1.5);
              complex<int> c2(2, 6);
      }
    
  • Function Templates函数模板

      stone r1(2, 3), r2(3, 3), r3;
      r3 = min(r1, r2);
    
  • 编译器对function template进行实参推导(argument deduction)

      template<class T>
      inline const T& min(const T& a, const T& b)
      {
              return b < a ? b : a;
      }
    
  • 实参推导的结果,T为stone,于是调用stone::operator<()

      class stone
      {
      public:
              stone(int w, int h, int we):_w(w), _h(h), _weight(we) { }
              bool operator<(const stone& rhs) const
              {
                      return _weight < ths._weight;
              }
      private:
            int _w, _h, _weight;
      };
    
  • Member Templates,成员模板

      template<class T1, class T2>
      struct pair
      {
              typedef T1 first_type;
              typedef T2 second_type;
              T1 first;
              T1 second;
              pair() : first(T1()), second(T2()) { }
              pair(const T1& a, const T2& b) : first(a), second(b) { }
        #ifdef __STL_MEMBER_TEMPLATES
              template<class U1, class U2>
              pair(const pair<U1, U2>& p) : first(p.first), second(p.second) { }
        #endif
      };
    
  • generalization,泛化

      struct __true_type { };
      struct __false_type { };
    
      template<class type>
      struct __type_trait
      {
              typedef __true_type this_dummy_number_must_be_first;
              typedef __false_type has_trivial_default_constructor;
              typedef __false_type has_trivial_copy_constructor;
              typedef __false_type has_trivial_assignment_operator;
              typedef __false_type has_trivial_destructor;
              typedef __false_type is_POD_type;
      };
    
  • Specialization,特化

      template<>
      struct __type_trait<int>
      {
              typedef __false_type has_trivial_default_constructor;
              typedef __false_type has_trivial_copy_constructor;
              typedef __false_type has_trivial_assignment_operator;
              typedef __false_type has_trivial_destructor;
              typedef __false_type is_POD_type;
      };
    
      template<>
      struct __type_trait<double>
      {
              typedef __false_type has_trivial_default_constructor;
              typedef __false_type has_trivial_copy_constructor;
              typedef __false_type has_trivial_assignment_operator;
              typedef __false_type has_trivial_destructor;
              typedef __false_type is_POD_type;
      };
    
  • Partial Specialization,偏特化

    偏特化代码示例

3 分配器

    1. 分配器allocator在vc6.0下的实现如下所示:
      allocator实现
  • VC6.0allocator只是以::operator new::operator delete完成allocate()deallocate,没有任何特殊的设计。

  • 其中int *p = allocator<int>().allocate(512, (int*)0); allocator<int>().deallocate(p, 512);表示利用allocate分配得到了一个指针p存放了512个int,利用deallocate归返了指针pallocator<int>()表示产生了一个临时对象。

    1. 分配器allocatorBorland C++下的实现如下所示:
      allocator实现
  • Borland C++allocator只是以::operator new::operator delete完成allocate()deallocate,没有任何特殊的设计。

    1. 分配器allocatorG2.9下的实现如下所示:
      allocator实现

      注意:右边的注解说明G2.9中没有使用该分配器,而是使用了SGI的STL分配器。
  • G2.9 STLallocator的使用如下图所示:

    allocator使用

  • 其中使用的分配器名字为alloc,而不是像其他库中使用了allocator

  • G2.9alloc实现如下:

    alloc实现

4 容器之间实现关系与分类

  • 本图以缩排形式表达“基层与衍生层”的关系。这里的衍生层并非继承(inheritance)而是复合(composition)。


    容器结构分类图
  • 容器及其迭代器的sizeof()大小


    容器和迭代器大小

5 深度探索list

  • 容器list的结构和实现如下图所示:
    结构和实现代码
  • list的迭代器interator实现如下:
    iterator实现
  • iterator++++iterator的实现说明:
    iterator++和++iterator

6 迭代器的设计原则和interator traits的作用与设计

  • iterator需要遵循的原则
    iterator原则
  • 其中traits需要的五个accociated types,如下所示:
    associate types
  • iterator Traits用以分离class iteratorsnon-class iterators
    Iterator Traits
不同iterator的iterator traits
  • 完整的iterator_traits
    iterator_traits
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,319评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,801评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,567评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,156评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,019评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,090评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,500评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,192评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,474评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,566评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,338评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,212评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,572评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,890评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,169评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,478评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,661评论 2 335

推荐阅读更多精彩内容