您的位置:首页 > 其它

《stl源码剖析》-- 内存基本处理工具

2015-01-29 11:28 309 查看
STL定义有五个全局函数,作用于未初始化空间上,它们分别是:construct(), destroy(), uninialized_copy(), uninialized_fill()和uninialized_fill_n()。

其中前两个函数前文已经介绍,这里就着重介绍后三个函数。

函数的作用

uninialized_copy()函数

函数原型:

template <class InputIterator, class ForwardIterator>
inline ForwardIterator
uninitialized_copy(InputIterator first, InputIterator last,
ForwardIterator result) ;
如果[result, result+(last-first))范围内的每一个迭代器都指向未初始化区域,则该函数会使用copy_constructor,给身为输入来源[first, last)范围内的每一个对象产生一个副品,

放进输出范围中,也就是说使用[first, last)范围内的元素初始化对应的[result, result+(last-first))元素。

uninialized_fill函数

函数原型:

template <class ForwardIterator, class T>
inline void uninitialized_fill(ForwardIterator first, ForwardIterator last, const T& x);
如果[first, last)范围内的每个迭代器都指向未初始化区域,那么该函数会在该范围内产生x的复制品。也就是说使用x初始化范围[first, last)的每一个元素。

uninialized_fill_n函数

函数原型:

template <class ForwardIterator, class Size, class T>
inline ForwardIterator uninitialized_fill_n(ForwardIterator first, Size n, const T& x);
如果[first, first+n)范围内的每个迭代器都指向未初始化区域,那么该函数会在该范围内产生x的复制品。也就是说使用x初始化范围[first, first+n)的每一个元素。

C++标准对这三个函数都有一个要求:具有commit or roolback语意,意思是要么初始化所有的元素,要么(当其中有一个元素初始化失败时)不构造任何东西。

函数的实现

这三个函数的实现思路完全一样,明白了一个如何实现,自然也就明白了另外两个。

我们就以uninialized_copy()函数为例来分析函数的实现。

uninialized_copy()函数的实现如下图所示:



实现代码如下(省去了异常处理):

//__uninitialized_copy_aux
template <class InputIterator, class ForwardIterator>
inline ForwardIterator
__uninitialized_copy_aux(InputIterator first, InputIterator last,
ForwardIterator result,
__true_type) {
return copy(first, last, result);  //copy函数仅仅只做赋值操作,不会调用任何构造函数
}

template <class InputIterator, class ForwardIterator>
ForwardIterator
__uninitialized_copy_aux(InputIterator first, InputIterator last,
ForwardIterator result,
__falst_type) {
ForwardIterator cur = result;

for ( ;first != last; ++first, ++cur)
construct(&*cur, *first);       //构造函数,实现2.2.3节已经给出

return cur;
}

//__uninitialized_copy
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()); //判断T是否是POD类型
}

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

//两个特化函数
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_fill()和uninitialized_fill_n()实现代码,思路和uninitialized_copy()函数完全一样

//////////////////////////////////////////////////////////////////////
/////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);       //直接把x的值放入内存区块,不调用构造函数
}

inline void
__uninitialized_fill_aux(ForwardIterator first, ForwardIterator last,
const T& x, __true_type)
{
ForwardIterator cur = first;
for ( ; cur != last; cur++)
construct(&*cur, x);
}

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_copy_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_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>
inline ForwardIterator
__uninitialized_fill_n_aux(ForwardIterator first, Size n,
const T& x, __falst_type) {
ForwardIterator cur = first;

for (; n > 0; --n, ++cur)
construct(&*cur, x);
return 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));
}


这三个函数会对STL中容器的实现有很大帮助。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: