STL内存处理工具

来源:互联网 发布:vscode c 插件 编辑:程序博客网 时间:2024/06/05 00:29

STL定义了5个全局函数,作用在未初始化的空间上。
1. construct()
2. destroy()
3. uninitialized_copy()
4. uninitialized_fill()
5. uninitialized_fill_n()

1. construct()与destroy()

见SGI内存管理http://blog.csdn.net/charles1e/article/details/51870785

2. uninitialized_copy()

这个函数的作用是把[first, last)范围的对象复制到result中。如果没有初始化,则使用copy constructor,复制对象。

template <class InputIterator, class ForwardIterator>inline ForwardIterator  uninitialized_copy(InputIterator first, InputIterator last,                     ForwardIterator result) {  return __uninitialized_copy(first, last, result, value_type(result));}

判断是否为POD(Plain Old Data),为标量类型或者传统的C struct类型.

template <class InputIterator, class ForwardIterator, class T>inline ForwardIterator__uninitialized_copy(InputIterator first, InputIterator last,                     ForwardIterator result, T*) {  typedef typename __type_traits<T>::is_POD_type is_POD;  return __uninitialized_copy_aux(first, last, result, is_POD());}

POD类类型就是指class、struct、union,且不具有用户定义的构造函数、析构函数、拷贝算子、赋值算子;不具有继承关系,因此没有基类;不具有虚函数,所以就没有虚表;非静态数据成员没有私有或保护属性的、没有引用类型的、没有非POD类类型的(即嵌套类都必须是POD)、没有指针到成员类型的(因为这个类型内含了this指针)。简单的说直接的内存复制操作对POD类型没有影响,比如用memset进行初始化,但这对于非POD类型是不可行的,比如存在虚函数的情况下。对于POD类型我们采用最有效率的复制手法,而对于no-POD类型的采取最安全的做法。

uninitialized_copy()使内存的配置与对象的构造分离,针对不同的对象有不同的构造方法,最终调用的这两个构造函数为

// Valid if copy construction is equivalent to assignment, and if the//  destructor is trivial.template <class InputIterator, class ForwardIterator>inline ForwardIterator __uninitialized_copy_aux(InputIterator first, InputIterator last,                         ForwardIterator result,                         __true_type) {  return copy(first, last, result);//调用STL的copy}template <class InputIterator, class ForwardIterator>ForwardIterator __uninitialized_copy_aux(InputIterator first, InputIterator last,                         ForwardIterator result,                         __false_type) {  ForwardIterator cur = result;  __STL_TRY {    for ( ; first != last; ++first, ++cur)      construct(&*cur, *first);//非POD,一个一个构造    return cur;  }  __STL_UNWIND(destroy(result, cur));}//一下针对char*和wchar_t*使用更高效的memmove()inline char* uninitialized_copy(const char* first, const char* last,                                char* result) {  memmove(result, first, last - first);  return result + (last - first);}inline wchar_t* uninitialized_copy(const wchar_t* first, const wchar_t* last,                                   wchar_t* result) {  memmove(result, first, sizeof(wchar_t) * (last - first));  return result + (last - first);}

3. uninitialized_fill()

uninitialized_fill也将内存配置与对象的构造分离,对[first, last)范围的迭代器i,调用construct(&*i, x);

inline void uninitialized_fill(ForwardIterator first, ForwardIterator last,                                const T& x) {  __uninitialized_fill(first, last, x, value_type(first));}

萃取出value_type

template <class ForwardIterator, class T, class T1>inline void __uninitialized_fill(ForwardIterator first, ForwardIterator last,                                  const T& x, T1*) {  typedef typename __type_traits<T1>::is_POD_type is_POD;  __uninitialized_fill_aux(first, last, x, is_POD());}

对不同的情况,有不同的处理方式

template <class ForwardIterator, class T>inline void__uninitialized_fill_aux(ForwardIterator first, ForwardIterator last,                          const T& x, __true_type){  fill(first, last, x);//STL的fill}template <class ForwardIterator, class T>void__uninitialized_fill_aux(ForwardIterator first, ForwardIterator last,                          const T& x, __false_type){  ForwardIterator cur = first;  __STL_TRY {    for ( ; cur != last; ++cur)      construct(&*cur, x);  //一个一个构造  }  __STL_UNWIND(destroy(first, cur));}

4. uninitialized_fill_n()

uninitialized_fill_n在[first, first+n)上填充x

template <class ForwardIterator, class Size, class T>inline ForwardIterator uninitialized_fill_n(ForwardIterator first, Size n,                                            const T& x) {  return __uninitialized_fill_n(first, n, x, value_type(first));}

然后萃取value_type

template <class ForwardIterator, class Size, class T, class T1>inline ForwardIterator __uninitialized_fill_n(ForwardIterator first, Size n,                                              const T& x, T1*) {  typedef typename __type_traits<T1>::is_POD_type is_POD;  return __uninitialized_fill_n_aux(first, n, x, is_POD());}

对具体问题,有不同的处理

template <class ForwardIterator, class Size, class T>inline ForwardIterator__uninitialized_fill_n_aux(ForwardIterator first, Size n,                           const T& x, __true_type) {  return fill_n(first, n, x);//对于POD,直接调用fill_n}template <class ForwardIterator, class Size, class T>ForwardIterator__uninitialized_fill_n_aux(ForwardIterator first, Size n,                           const T& x, __false_type) {  ForwardIterator cur = first;  __STL_TRY {    for ( ; n > 0; --n, ++cur)      construct(&*cur, x);      //对于非POD,要调用construct    return cur;  }  __STL_UNWIND(destroy(first, cur));}

 5.三种内存基本函数的泛型版本如图所示

三种内存基本函数的泛型版本

0 0
原创粉丝点击