STL源码剖析之STL简介与STL配置器

1从底层来看,STL带给我们一套具有实用价值的零部件,以及一个整合起来的整体,STL中组件之间耦合度很低,组件之间可以互相关联整合

2STL以泛型思维,描述了很多抽象概念,以抽象概念为主体而不是依赖于实际的类

3STL六大组件:

容器 : 数据结构(容纳数据)是一种class template

算法 : 常用的算法,是一种function template

迭代器:容器和算法之间的胶合剂,也是一种泛型组件,“泛型指针”,每个容器都有自己的迭代器,只有容器自己才知道如何使用自己的迭代器来完成迭代。

仿函数:类静态函数

适配器修饰容器或者仿函数或者迭代器接口的东西,也就是改变了被适配的东西,提供了新的接口

配置器空间配置和管理

4六大组件的关系

Container通过allocator取得数据的存储空间,Algorithm通过Iterator 存取 container的内容,functor协助algorithm完成不同策略的变化,adapter可以修饰functor

5allocator的简单定义

#include

template

classallocator

{

public:

typedef T value_type; //实际类型

typedef T* pointer; //实际类型的指针类型

typedef const T* const_pointer; //实际类型的常指针类型

typedef T& reference; //实际类型的引用类型

typedef const T& const_reference; //实际类型的常引用类型

typedef size_t size_type; //cstddef中的size_t,和ptrdiff_t

//存在于C标准库的头文件stddef的C++版cstddef

//size_t源类型是unsigned int,使用sizeof返回的类型就是size_t

//作用:avoid specifying machine-dependent data size,提高代码可移植性

typedef ptrdiff_t difference_type;

//两个指针差的类型,因为不一定和int一样,于平台有关。

template

struct rebind

{ typedef allocator other;};

pointer allocater(size_type n, const voidhint=0) //分配空间*

{

return _allocate( (difference_type)n, (pointer)0 );//使用ptrdiff_t来得到独立于平台的地址差值

/ _allocate的实现*

template

inline T _allocate(ptrdiff_t size,T)

{

T tmp=(T) (::operator new((size_t)(size*sizeof(T))) );

// C++中使用operator new来分配空间,注意这里使用的是size_t来作为空间大小的类型

if (tmp==0)

exit(1);

return tmp;

}

*/

//泛型思想,为特定大小的区间分配内存,返回指针

}

}

void deallocate(pointer p, size_type n)

{

_deallocate(p);

/*

template

inline void _deallocate(T* buffer)//泛型思想,operator delete

{

::operator delete(buffer);

}

*/

}

void construct(pointer p, const T& value) //构造对象

{

_construct(p,value);

/*

template

inline void _construct(T1* p,const T2& value)

{

new(p) T1(value); //使用placement new

}

*/

}

void destroy(pointer p)

{

_destroy(p);

/*

template

inline void _destroy(T* ptr)

{

ptr->~T();

}

*/

}

pointer address(reference x)

{

return (pointer)&x; //返回对象的地址(指针)

}

const_pointer const_address(const_reference x);

{

return (const_pointer)&x;

}

size_type max_size() const

{

return size_type( UINT_MAX / sizeof(T) ); //可成功配置的最大

}

};

// vector > iv(ia,ia+5);

// 底层上使用allocator来分配适当的空间,来存取数据等

6SGI STL中的配置器是这样使用的std::alloc,而我们通常会使用缺省的空间配置器,所以SGI STL为每个容器都提供了默认参数说明空间配置器

Template

Class vector{};

7[5]中所定义的allocator只是基层内存配置和释放(::operator new和::operator delete)的一层薄薄的包装,并没有考虑到效率上的优化。是SGI所定义的一个符合部分标准的配置器,

【6】中所说的是正式使用的alloc,是特殊的空间配置器,内部使用

8配置器定义在memory文件中,而该文件包含了stl_alloc,stl_construct(一个完成内存分配,一个完成构造)

9stl_construct的实现(内存配置前对象的构造行为)

#include

template

inline void construct(T1*p,const T2& value)

{

new(p) T1(value); // placement new 调用T1::T1(value)

}

template

inline void destroy(T* pointer) //接受单个指针,直接调用析构函数

{

pointer->~T();

}

template

inline void destroy(ForwardIterator first,ForwardIterator last)

//接受两个迭代器,删除区间对象

{

__destroy(first,last ,value_type(first);

//但是如果每个对象的析构函数都是trivial即无关痛痒的,就没必要一次一次调用析构

//所以这里使用value_type来获得对象的类型,再利用__type_trait来判断是不是无关痛痒的

//这里是trait的用法,后面会说到

}

template

inline void __destroy(ForwardIterator first,ForwardIterator last,T*)

{

typedef typename__type_trait::has_trivial_destructor trivial_destructor;

__destroy_aux(first,last,trivial_destructor());

//根据传入的对象类型,使用tribial_destructor来判断是不是无关痛痒的

}

template

inline void __destroy_aux(ForwardIterator first,ForwardIterator last,__false_type)

{

for(;first<last;++first)

destroy(&*first);

}

template

inline void __destroy_aux(ForwardIterator,ForwardIterator,__true_type)

{ //释放内存空间

}

inline void destroy(char,char){}

inline void destroy(wchar_t,wchar_t){}

clip_image002

clip_image004

这是一种考虑到效率的construct和destroy!!!!!!因为在destroy时可以根据对象是否为trivial来调整destroy的策略

10前面是内存配置后的 对象构造内存释放前的 对象析构,下面是具体的内存的配置和释放。

对象构造前的空间配置对象构造后的空间释放由<stl_alloc.h>负责。

在空间的配置和释放(alloc, 对象的构造construct)时要考虑:

1 堆空间申请

2 多线程情况

3 内存不足

4 内存碎片

C++的内存配置基本操作是::operator new() ::operator delete()这是两个“全局函数”,相当于C的malloc和free

下一篇将学习到SGI关于内存配置的策略。
原文链接: https://www.cnblogs.com/aga-j/archive/2011/06/04/2072517.html

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/26740

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年2月8日 上午4:23
下一篇 2023年2月8日 上午4:23

相关推荐