C/C++泛型编程(4)容器

1.数组Array:语言自身唯一支持的最简化的数据结构。数组可以存放一系列元素,而且可以遍历那些元素。与数组相关的iterator就是指针。

C/C++数组优点:(1)遵循range概念。A是具有N个元素的数组,则A+N是一个越过尾端的指针。A内所有元素包含在range[A,A+N)中。(2)数组分配在栈中,数组不必以动态方式分配内存(即malloc或new)。(3)数组很有效率,不必通过间接动作访问某一元素。(4)数组有固定大小,且在编译器就知道了。(5)具有方便的初始化语法。int A[6]={1,3,5,7,9}

C/C++数组缺点:(1)数组没有size(),应用程序必须明白记录数组大小。(2)无法用直接方法获取数组结尾的iterator。(3)无法直接复制数组。如果想要复制,必须自己写个循环处理。(4)数组无法以传值方式传入某个函数。

 

2.块Block:它是一个由元素构成的简单而连续的区块。只比C数组的一层外包装再多一些东西。可以这样声明一个容纳10个整数的block:block<int,10> A;而且可以普通的数组语法如A[1]取用某个元素。

Block声明提供了一对iterators(T*,const T*),其中有可变和不可变的;提供一个由mutable至constant的转换方式。每个iterator具有value type,difference type,reference type和pointer type4种型别。注意:当两个iterators组成一对时,他们必须具备相同的value_type和difference_type。

template <class T,size_t N>

struct block{

 typedef T value_type;  //value_type 是对象型别

 typedef value_type* pointer;  //型别为value_type之对象的指针,与iterator的pointer type同型。

 typedef const value_type* const_pointer;//型别为value_type之对象的const指针,与const_iterator的pointer type同型。

 typedef value_type& reference;

 typedef const value_type& const_reference;

 typedef ptrdiff_t difference_type; //用于减算,有正负值;非负的difference_type就是size_type

 typedef size_t size_type;   //表示block中的元素个数或是某特定元素的索引值。用于计数。

 typedef pointer iterator;  //iterator就是指针(可变)

 typedef const pointer const_iterator; //iterator就是指针(不变)

 typedef reverse_iterator<const_iterator>  const_reverse_iterator; //反转迭代(不变)

 typedef reverse_iterator<iterator> reverse_iterator;  //反转迭代(可变)

  iterator begin(){return data;}

  iterator end(){return data+N;}

 

  const_iterator begin(){return data;}

  const_iterator end(){return data+N;}

 

  reverse_iterator rbegin() {return reverse_iterator(end());}

  reverse_iterator rend(){return reverse_iterator(begin());}

 

  const_reverse_iterator rbegin() {return const_reverse_iterator(end());}

  const_reverse_iterator rend(){return const_reverse_iterator(begin());}

 

  reference operator[](size_type n){return data[n];}

  const_reference operatorp[](size_type n) const {return data[n];}

  size_type size() const{return N;}

  size_type max_size() const{return N;}

  bool empty() const{return N==0;}

 

  void swap(block& x){

    for(size_t n=0;n<N;++n){

     std::swap(data[n],x.data[n]);

    }

  }

  T data[N];

};

 

【注意】block是一个sturct,没有构造函数和析构函数,没有关键字。其所有成员包含数组data自身都是public.

 

3.全局函数方式实现operator==和operator<

template <class T,size_t N>

bool operator==(const block<T,N>& x,const block<T,N>& y){

 for (size_t n=0;n<N;++n){

  if(x.data[n]!=y.data[n]){

    return false;

  }

  return true;

 }

}

 

template <class T,size_t N>

bool operator<(const block<T,N>& x,const block<T,N>& y){

  for(size_t n=0;n<N;++n){

    if(x.data[n]<y.data[n]){

      return true;

    }else if(x.data[n]>x.data[n]){

      return false;

   }

   return false;

  }

}

 

4. Iterators 有三种不同的方式可以访问block元素:

(1)block类定义了嵌套型别iterator和const_iterator,而block A的所有元素都包含于range[A.begin(),A.end())之中。

(2)相对于iterator和const_iterator,嵌套型别reverse_iterator和const_reverse_iterator是反向的iterator型别。range[A.rbegin(),A.rend()]所包含的元素与{A.begin(),A.end()}相同,但排序次序相反。

(3)如果n是一个整数,表达式A[n]返回第n个元素。

 

5.可变大小的容器:

STL定义2种可变大小的容器:序列容器(Sequences)、配置器容器(Associative)

(1)Sequences容器:是Forward容器的一个强化,是一种最明显的大小可变的容器。序列容器以严格线性顺序的range来呈现其元素。不但可以获取任何元素,而且可以在range任一点新增或删除元素。Sequence具有insert() 安插元素、erase()删除元素功能函数。s.insert(p,x);s.erase(p);

注意:对于vector来说,安插insert()是一个非常缓慢的操作;相较之下,list是以节点为基础的容器,其iterators属于双向迭代器,安插insert()并不会涉及任何既有元素的移动,也不会造成任何iterators无效。

Sequence的强化:Back Insertion Sequence\Front Insert Sequence

a.Front Insert Sequence具有三个特别的成员函数:front 返回容器第一个元素\push_front 开头安插新元素\pop_front 删除第一个元素。

b.Back Insertion Sequence具有三个对应的成员函数:back 返回容器最后一个元素\push_back 尾部安插新元素\pop_back 删除最后一个元素

(2)Associative容器:让client控制class某些方面的行为,可以将这些行为封装成为一个template参数,类似于采用函数对象的方式。但我们不使用函数对象的方式,因为内存分配涉及数个不同的操作行为(至少涉及分配函数与归还函数,而这两者必须具有一致性,即不能以new分配内存却以free归还)

容器内存管理策略:由一个template参数定义之,这个参数是Allocator,用来处理所有的内存分配与归还行动。

 

6.容器的阶层架构:

C/C++泛型编程(4)容器

一般法则:尽可能使用最简单的容器类。如果不想在容器类内频繁地做安插动作,vector可能是最有效率的选择。如果你永远也不会改动容器的大小(甚至在编译期就知道大小),那么使用block。如果要频繁的执行安插动作,就应使用诸如list或slist之类的容器,它们专为【将元素安插于容器之内】而设计的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值