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
// 底层上使用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
__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){}
这是一种考虑到效率的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
非原创文章文中已经注明原地址,如有侵权,联系删除
关注公众号【高性能架构探索】,第一时间获取最新文章
转载文章受原作者版权保护。转载请注明原作者出处!