一、内存基本处理工具
STL定义有五个全局函数,作用于未初始化空间上。前两个函数是用于构造的 construct() 和用于析构的 destroy(),另三个函数 uninitialized_copy(),uninitialized_fill(),uninitialized_fill_n(),分别对应于高层次函数 copy()、fill()、fill_n() —— 这些都是STL算法。SGI把它们都定义于<stl_uninitialized>。
1. uninitialized_copy
// 如果 copy construction 等同于 assignment,而且 destructor 是 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); // 必须一个一个元素地构造,无法批量进行 return cur; } __STL_UNWIND(destroy(result, cur)); } // POD 意指 Plain Old Data,也就是标量型别(scalar types)或传统的 C struct 型别。 // POD 型别必然拥有 trivial ctor/dtor/copy/assignment函数。 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()); // 利用 is_POD() 所获得的结果,让编译器做参数推导 } template <class InputIterator, class ForwardIterator> inline ForwardIterator uninitialized_copy(InputIterator first, InputIterator last, ForwardIterator result) { return __uninitialized_copy(first, last, result, value_type(result)); // 利用 value_type() 取出 result 的 value type } // 针对 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); }
uninitialized_copy() 使我们能够将内存的配置与对象的构造行为分离开来。如果作为输出目的地的 [result, result + (last - first)) 范围内的每一个迭代器都指向未初始化区域,则 uninitialized_copy() 会使用 copy constructor,给身为输入来源之 [first, last) 范围内的每一个对象产生一份复制品,放进输出范围中。
C++标准规格书要求 uninitialized_copy() 具有 “commit or rollback” 语意,意思是要么“构造出所有必要元素”,要么(当有任何一个 copy constructor失败时)“不构造任何东西”。
2. uninitialized_fill
template <class ForwardIterator, class T> inline void __uninitialized_fill_aux(ForwardIterator first, ForwardIterator last, const T& x, __true_type) { fill(first, last, x); } 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)); } 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(ForwardIterator first, ForwardIterator last, const T& x) { __uninitialized_fill(first, last, x, value_type(first)); }uninitialized_fill() 也能够使我们将内存配置与对象的构造行为分离开来。如果[first, last) 范围内的每个迭代器都指向未初始话的内存,那么uninitialized_fill() 会在该范围内产生 x(上式第三个参数)的复制品。
与 uninitialized_copy() 一样,uninitialized_fill() 必须具备 “commit or rollback” 语意。
3. uninitialized_fill_n
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); } 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); return cur; } __STL_UNWIND(destroy(first, cur)); } 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(ForwardIterator first, Size n, const T& x) { return __uninitialized_fill_n(first, n, x, value_type(first)); }uninitialized_fill_n() 能够使我们将内存配置与对象构造行为分离开来。它会为指定范围内的所有元素设定相同的初值。如果 [ first, first + n) 范围内的每一个迭代器都指向未初始化的内存,那么 uninitialized_fill_n() 会调用 copy constructor,在该范围内产生 x(上式第三个参数)的复制品。
uninitialized_fill_n() 也具有 "commit or rollback"语意。