织梦CMS - 轻松建站从此开始!

罗索

C++ 标准模板库组件介绍

落鹤生 发布于 2012-09-22 13:54 点击:次 
落鹤生:这么多年来自己用STL也写了无数的代码,什么东西该怎么用已经滚瓜烂熟,许多功能的原理也已经很理解,但的确就像这位作者那样,如果有人来问题你一些问题,可能还是会卡壳,就像作者被问的这种题:标准模板库的继承体系?对于这种题,我只想说:WTF.
TAG:

在前几天的阿里面试过程中,问到了我标准模板库的继承体系。平时开发对vector,list, map,set ,stack等容器用的比较多,但是没有深入研究过。经历过面试,发现了很多需要完善和提高的地方。
但是有个问题哦,标准模板库中得几大组件没有啥继承关系,只是说有某些容器之间有适配关系。

Container(容器):

所谓容器,就是存放数据的仓库,定义了数据在内存中的组织方式,

 

主要:有序列式容器(线性数据结构)、关联连式容器(非线性数据结构:树结构)

 

序列容器,典型的容器vector,相对于C++内嵌的数组,vector的优点是支持数据的动态扩展。

 

而空间的动态扩展,有空间配置器配置。它会为容器提供空间分配的策略,比如空间不够时增长的幅度。

关联式容器:关联式容器的思想类似于关系数据库,由key-value组成。 主要分为map和set,hash及其相关衍生.

 

Iteraotrs(迭代器):

迭代器统一了容器的访问操作,很好的东西。想到了迭代器模式

  1. Container<Type> cons; 
  2. for (Container<Type>::iterator iter = cons.begin();  
  3.      iter != cons.end(); iter++) 
  4.     visit(iter); 

看看《STL源码分析》中关于vector的定义

  1. template<class T, class Alloc = alloc> 
  2. class vector 
  3.     typedef T value_type; 
  4.     typedef value_type* pointer; 
  5.     typedef value_type* iterator; 
  6.     ...... 

这里很明显的是通过typedef定义将指针定义为vector的迭代器,提供统一访问,但是本质上还是指针哈。

VC的vector的迭代器定义:是一个类哈,有许多数据组成了迭代器的定义,其中有指针,有引用。

  1. template<class _Myvec> 
  2.     class _Vector_iterator 
  3.         : public _Vector_const_iterator<_Myvec> 
  4.     {   // iterator for mutable vector 
  5. public
  6.     typedef _Vector_iterator<_Myvec> _Myiter; 
  7.     typedef _Vector_const_iterator<_Myvec> _Mybase; 
  8.     typedef random_access_iterator_tag iterator_category; 
  9.  
  10.     typedef typename _Myvec::value_type value_type; 
  11.     typedef typename _Myvec::difference_type difference_type; 
  12.     typedef typename _Myvec::pointer pointer; 
  13.     typedef typename _Myvec::reference reference; 
  14.         ...... 

pointer定义,就是某个数据类型的指针

  1. typedef value_type _FARQ *pointer; 

再看下hashtable中的迭代器的定义:

  1. ...... 
  2. struct _hashtable_iterator 
  3.     ...... 
  4.     node* cur; 
  5.     hashtable* ht; 
  6.     ..... 

在hashtable迭代器中,有两个指针,一是当前节点的指针,二是buckets vector的指针。

综上所述,所谓迭代器,就是对指针以及其他辅助信息的一个封装。对数据的访问一定是通过地址访问,地址是必须的,所以地址是迭代器中不可缺少的信息。
在迭代器的使用中,常常遇到的一个问题就是,在进行数据的插入删除时的失效问题!其实就是指针的问题哈

Allocator(空间配置器):

空间配置器用于屏蔽容器关于内存管理的细节。比如容器内存的申请释放,当内存不够时采用怎样的一种策略。在我们平常的使用中,

  1. vector<strudent> stus; 

并没有制定容器的空间配置方案,于是采用默认的配置方案,其实我们是可以自己编写空间配置方案,并将该方案实施于某个容器。(CustomAlloc是自定义的命名空间,并实现了空间配置方案allocator)

  1. vector<int, CustomAlloc::allocator<int>> datas; 

可以在自定义的方案中进行内存管理。

Algorithms(算法):

提供了大量常用、通过的算法,比如比较、查询、数据移动、复制、交换等等。
基础算法:min, max, swap
排序:sort
替换:replace
查找:find
此处不一一列举

Function Objects(函数对象):

函数对象,简单的理解就是将一个函数封装为对象,但是它的作用是为容器的操作提供依据。我进行比较大小,根据什么比,函数对象提供,查询,匹配的规则是什么,函数对象提供。

 

例如:

 

1. 对vector容器进行排序,排序的标准是?

 

2. 对容器中得数据进行查询,查询的标准是?

 

通过函数对象,可以灵活的编写操作依据,并注入到操作函数中。

 

为sort函数编写Compare()

 

为find_if编写Query()

此处写了个实例,说明一下用法:
业务对象定义:

  1. class student 
  2. public
  3.         string name; 
  4.         int age; 
  5.  
  6.         student(string name, int age) 
  7.         { 
  8.              this->name = name; 
  9.              this->age = age; 
  10.         } 
  11.  
  12.         student(const student &stu) 
  13.         { 
  14.                 *this = stu; 
  15.         } 
  16.  
  17.         student& operator=(const student &stu) 
  18.         { 
  19.             this->name = stu.name; 
  20.             this->age = stu.age; 
  21.             return *this
  22.         } 
  23. }; 

函数对象定义,说明对象之间比较的依据,此处依据是年龄

  1. struct Compare : public std::binary_function<student, student, bool
  2.     bool operator()(const student stu1, const student stu2) const 
  3.     { 
  4.             if (stu1.age < stu2.age) 
  5.                 return true
  6.             else  
  7.                 return false
  8.     } 
  9. }; 

测试程序:

  1. int _tmain(int argc, _TCHAR* argv[]) 
  2.     vector<student> stus; 
  3.     srand((unsigned int)time(NULL)); 
  4.     string strName = "student"
  5.     for (int i = 0; i < 10; i++) 
  6.     { 
  7.         int val = rand()/10; 
  8.         char dataBuf[20]; 
  9.         memset(dataBuf, 0, 20); 
  10.         itoa(val, dataBuf, 10); 
  11.         student stu(dataBuf, val); 
  12.         stus.push_back(stu); 
  13.     } 
  14.  
  15.     for (vector<student>::iterator iter = stus.begin(); iter != stus.end(); iter++) 
  16.         cout<<iter->name<<"--"<< iter->age<<endl; 
  17.     cout<<"-----------------------------"<<endl; 
  18.     sort(stus.begin(), stus.end(),  Compare()); 
  19.     for (vector<student>::iterator iter = stus.begin(); iter != stus.end(); iter++) 
  20.         cout<<iter->name<<"--"<< iter->age<<endl; 
  21.  
  22.     getchar(); 
  23.     return 0; 

测试结果:将原本随机插入的数据根据年龄进行了排序

 

注:此处是对几个组件的简要说明,并未详细深入

(西昆仑)
本站文章除注明转载外,均为本站原创或编译欢迎任何形式的转载,但请务必注明出处,尊重他人劳动,同学习共成长。转载请注明:文章转载自:罗索实验室 [http://www.rosoo.net/a/201209/16283.html]
本文出处:OSChina 作者:西昆仑 原文
顶一下
(0)
0%
踩一下
(0)
0%
------分隔线----------------------------
发表评论
请自觉遵守互联网相关的政策法规,严禁发布色情、暴力、反动的言论。
评价:
表情:
用户名: 验证码:点击我更换图片
栏目列表
将本文分享到微信
织梦二维码生成器
推荐内容