【vc++精品源码栏目提醒】:以下是网学会员为您推荐的vc++精品源码-STL源码剖析笔记 - 大学课件,希望本篇文章对您学习有所帮助。
第1章 STL 概论1.2 STL 六大组件STL 提供六大组件,彼此可以组合套用:1.容器(container):各种数据结构,如 vectorlistdequesetmap 等2.算法(algorithm) :各种常用算法如 sortsearchcopyerase......3.迭代器(iterator):扮演容器与算法之间的胶着剂。
所以 STL 容器都附带有自己专属的迭代器。
指针也是一种迭代器。
4.仿函式(functors) :行为类似函数,可作为算法的某种策略,从实现的角度讲,仿函式是一种重载了 operator的 class 或 class template。
仿函式是否就是 cprimer 中的函数对象?5.适配器(adaptor) :一种用来修饰容器或仿函式或迭代器接口的东西,有 function adaptor,container adaptor,iterator adaptor。
6.分配器(allocator) :负责空间分配与管理。
1.7 STLport 版本 STLport 版本是以 SGI STL 为蓝本的高度可移植性版本。
第 2 章 空间分配器2.1 空间配置器的标准接口根据 STL 规范,以下是 allocator 的必要接口:第一组:各种 type 类型//以下各种 type 的设计原由,第三章详述。
allocator::value_typeallocator::pointerallocator::const_pointerallocator::referenceallocator::const_referenceallocator::size_typeallocator::difference_type第二组:构造与析构函数Allocator::rebind一个嵌套的 (nested)class template。
class rebindltUgt拥有唯一成员 other, 那是一个 typedef,代表 allocatorltUgt。
allocator::allocator---默认构造函数allocator::allocatorconst allocatoramp---拷贝构造函数template ltclass Ugtallocator::allocatorconst allocatorltUgtamp --- 泛化的拷贝构造函数allocator::allocator---默认的析构函数第三组:取地址函数pointer allocator::addressreference x const ---传回某个对象的地址,算式 a.addressx等同于ampx。
const_pointer allocator::addressconst_reference x const --- 传回某个 const 对象的地址,算式a.addressx等同于ampx。
第四组:空间分配与释放pointer allocator::allocatesize_type n cosnt void 0 --- 配置空间,足以储存 n 个 T 对象。
第二自变量是个提示。
实作上可能会利用它来增进区域性(locality) ,或完全忽略之。
void allocator::deallocatepointer p size_type n ---归还先前分配的空间。
size_type allocator::max_size const --- 传回可成功分配的最大量。
第五组:construct 和 destroy 函数void allocator::constructpointer p const Tamp x --- 等同于 newconst void p Tx。
void allocator::destroypointer p --- 等同于 p-gtT。
2.1.1 设计一个空间配置器 JJ::allocator 在书中,侯捷先生写了一个分配器 JJ: :allocator。
代码见书。
2.2 具备 sub-alloction 的 SGI allocator SGI STL 配置器与标准规范不同,其名称是 alloc 而非 allocator,而且不接受任何自变量。
如果要在程序中使用 SGI STL 配置器,则不能采用标准写法: Vectorltint std::allocatorltintgtgt iv//在 vc 或 c builder 中这么写 Vectorltint std::allocgt iv //在 GCC 中这么写 但是令人欣慰的是,我们通常使用预设的空间配置器,很少需要自行指定配置器,而SGI STL 的每一个容器都已经指定其预设的空间配置器为 alloc。
2.2.1 SGI 标准的空间配置器 std::allocator 该配置器符号部分标准,但效率差,SGI 自己不用,也不建议我们使用。
2.2.2 SGI 特殊的空间配置器 std::alloc 看下面的代码: Class Foo ...... Foo of new Foo//配置内存,然后构造对象 Delete pf//将对象析构,然后释放内存 为 了 精 密 分 工 , STL alloctor 提 供 四 个 动 作 : alloc::allocate 负 责 内 存 分 配 ,alloc::deallocate负责内存释放,::construct 负责对象构造,::destroy负责对象析构。
配置器定义于ltmemorygt中,其中包括如下两个头文件: include ltstl_alloc.hgt //负责内存分配与释放 include ltstl_construct.hgt //负责对象构造和析构2.2.3 构造和析构函数:construct 和 destroy 下面代码是ltstl_construct.hgt中的部分内容: includeltnew.hgt //construct接受一个指针 p 和一个初值 value Templateltclass T1 class T2gt Inline void constructT1 p const T2amp value Newp T1value//placement new 用法调用构造函数 T1::T1value。
这里用到了 placement new,它能实现在指定的内存地址上用指定类型的构造函数构造一个对象 //destroy的第一个版本,接受一个指针 Templateltclass Tgt Inline void destroyT pointer Pointer-gtT //调用析构函数 T 在调用 destroy函数同时释放 n 个对象(假设类型为 T)时,SGI 提供了方法可以判定对象是否有 non-trivial destructortrival:琐碎的,无价值的,不重要的,如果没有则不必要循环为每个对象调用 T::T,以提高效率代码如下: //以下是 destroy的第二版本,接受两个迭代器,准备将first last范围内的所有物件析 //构掉,因为不知道这个范围有多大,万一很大,但是每个物件的析构函数都是无关痛 //痒的(triaval destructor),那么一次次呼叫这些无关痛痒的析构函数,对效率是一种损 //害,所以此函数设法找出元素的数值类型,进而利用__type_traitsltgt选 // 择 适 当 措 //施 template ltclass ForwardIteratorgt // __false_type 表明是具有 non trivial destructor,所以要循环调用 destroy inline void __destroy_auxForwardIterator first ForwardIterator last __false_type for first lt last first destroyampfirst template ltclass ForwardIteratorgt //__true_type 表明是具有 trivial destructor 不需要调用 destroy inline void __destroy_auxForwardIterator ForwardIterator __true_type //空函数体 //判断元素的型别,是否有 trival destructor template ltclass ForwardIterator class Tgt inline void __destroyForwardIterator first ForwardIterator last T typedef typename __type_traitsltTgt::has_trivial_destructor trivial_destructor __destroy_auxfirst last trivial_destructor template ltclass ForwardIteratorgt inline void destroyForwardIterator first ForwardIterator last __destroyfirst last value_typefirst //以下是 destroy第二版本针对迭代器为 char和 wchar的特化版 Inline void destroychar char Inline void destroywchar_t wcht_t 但是 c本身并不直接支持对“指针所指之物”的型别判断,也不支持“对象析构函数是否是 trival”的判断,这需要借助于 Traits 编程技法来完成的: typedef typename __type_traitsltTgt::has_trivial_destructor trivial_destructor 首先使用 value_type获取迭代器指向的物体类型,然后使用__type_traitsltTgt查看 T 是否有 non-trivial destructor。
2.2.4 空间的配置与释放 std::alloc 对象构造前的空间分配和对象析构之后的空间释放,由ltstl_alloc.hgt负责,SGI 对此的设计哲学如下: 向 system heap 申请空间; 考虑多线程情况; 考虑内存不足时的应对措施; 考虑过多小型区块可能造成的内存碎片(fragment)问题;下面摘录的代码都暂时没有考虑多线程情况的处理。
C内存分配基本动作是::operator
上一篇:
各种指标源码
下一篇:
浅析普外科围手术期抗菌药物的应用