《STL源码剖析》---stl_uninitialized阅读笔记

这节讲解在已分配但未初始化的空间上构造对象(可能是一段内存,构造多个对象)。 使内存的配置与对象的构造分离开来。在未初始化的内存上构造对象时,会先判断对象类型是否是POD类型。POD全称是Plain old data,也就是标量类型(基本类型和指针类型)或者传统的C struct类型。POD类型有trivial的constructor、deconstructor、copy、assignment(构造、析构、复制构造函数、赋值操作符)操作,所以对POD类型采用最有效的复制手法,而对non-POD类型采用最保险安全的做法。

对于non-POD类型,通常copy constructor和operator=不等价,所以要用constructor构造每个对象。

主要有四个函数:

1、uninitialized_copy

2、uninitialized_copy_n

3、uninitialized_fill

4、uninitialized_fill_n

G++ 2.91.57,cygnus\cygwin-b20\include\g++\stl_uninitialized.h 完整列表

/*
 *
 * Copyright (c) 1994
 * Hewlett-Packard Company
 *
 * Permission to use, copy, modify, distribute and sell this software
 * and its documentation for any purpose is hereby granted without fee,
 * provided that the above copyright notice appear in all copies and
 * that both that copyright notice and this permission notice appear
 * in supporting documentation.  Hewlett-Packard Company makes no
 * representations about the suitability of this software for any
 * purpose.  It is provided "as is" without express or implied warranty.
 *
 *
 * Copyright (c) 1996,1997
 * Silicon Graphics Computer Systems, Inc.
 *
 * Permission to use, copy, modify, distribute and sell this software
 * and its documentation for any purpose is hereby granted without fee,
 * provided that the above copyright notice appear in all copies and
 * that both that copyright notice and this permission notice appear
 * in supporting documentation.  Silicon Graphics makes no
 * representations about the suitability of this software for any
 * purpose.  It is provided "as is" without express or implied warranty.
 */

/* NOTE: This is an internal header file, included by other STL headers.
 *   You should not attempt to use it directly.
 */

#ifndef __SGI_STL_INTERNAL_UNINITIALIZED_H
#define __SGI_STL_INTERNAL_UNINITIALIZED_H

__STL_BEGIN_NAMESPACE

// 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) {//_true_type说明是POD类型
  return copy(first, last, result);//调用STL算法copy()
}

template <class InputIterator, class ForwardIterator>
ForwardIterator
__uninitialized_copy_aux(InputIterator first, InputIterator last,
                         ForwardIterator result,
                         __false_type) {//_false_type说明是non-POD类型,要一个一个的构建,无法批量进行
  ForwardIterator cur = result;
  __STL_TRY {
    for ( ; first != last; ++first, ++cur)//一个一个的构建
      construct(&*cur, *first);
    return cur;
  }
  __STL_UNWIND(destroy(result, cur));
}

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;//用来判断是不是POD类型
  return __uninitialized_copy_aux(first, last, result, is_POD());
}
/*
调用copy constructor,复制[first, last)范围内每一个对象,放到目的地[result, result+(last-first) )。
对于char*和wchar_t*提供特殊版本,获得更好效率
具有像数据库事物特性的commit和rollback特性,要么构造出所有必要元素,要么不够造任何东西。

		copy()               for(; first!=last) construct()
		|						  |
		| _true_type			  | _false_type
        <__特化____________特化__>
				   |
			_uninitialized_copy()
 <InputIterator, Inputterator, ForwardIterator>
				   |
				   |泛化
				   |
uninitialized _____|_____特化___>(const char*, const char*,char*) memmove()
_copy()			   |
				   |
    			   |____特化___>(const wchar_t*, const wchar_t*, wchar_t*) memmove()

*/
template <class InputIterator, class ForwardIterator>
inline ForwardIterator
  uninitialized_copy(InputIterator first, InputIterator last,
                     ForwardIterator result) {
  return __uninitialized_copy(first, last, result, value_type(result));
}
//char*版本
inline char* uninitialized_copy(const char* first, const char* last,
                                char* result) {
  memmove(result, first, last - first);
  return result + (last - first);
}
//wchar_t*版本
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);
}

//非随机存取迭代器类型input_iterator_tag
template <class InputIterator, class Size, class ForwardIterator>
pair<InputIterator, ForwardIterator>
__uninitialized_copy_n(InputIterator first, Size count,
                       ForwardIterator result,
                       input_iterator_tag) {
  ForwardIterator cur = result;
  __STL_TRY {
    for ( ; count > 0 ; --count, ++first, ++cur)
      construct(&*cur, *first);
    return pair<InputIterator, ForwardIterator>(first, cur);
  }
  __STL_UNWIND(destroy(result, cur));
}
//随机存取的迭代器
template <class RandomAccessIterator, class Size, class ForwardIterator>
inline pair<RandomAccessIterator, ForwardIterator>
__uninitialized_copy_n(RandomAccessIterator first, Size count,
                       ForwardIterator result,
                       random_access_iterator_tag) {
  RandomAccessIterator last = first + count;
  return make_pair(last, uninitialized_copy(first, last, result));
}
//用[result, result+count)初始化[first, first+cout)
/*
这个根据迭代器类型跳转
						 _____input_iterator_tag,调用construct(……)
						|
						|
uninitialized_copy_n----> iterator_category(first)?判断迭代器类型
						|
						|_____random_access_iterator_tag,调用uninitialized_copy(……)
*/
template <class InputIterator, class Size, class ForwardIterator>
inline pair<InputIterator, ForwardIterator>
uninitialized_copy_n(InputIterator first, Size count,
                     ForwardIterator result) {
  return __uninitialized_copy_n(first, count, result,
                                iterator_category(first));//判断迭代器类型
}

// Valid if copy construction is equivalent to assignment, and if the
//  destructor is trivial.
//如果复制构造函数和赋值操作符效果相同,且析构函数时trivial的
template <class ForwardIterator, class T>
inline void
__uninitialized_fill_aux(ForwardIterator first, ForwardIterator last,
                         const T& x, __true_type)//POD类型
{
  fill(first, last, x);
}

template <class ForwardIterator, class T>
void
__uninitialized_fill_aux(ForwardIterator first, ForwardIterator last,
                         const T& x, __false_type)//non-POD类型
{
  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());

}

/*
用x初始化空间[first, last)
						___>  construct(……)
						| __false_type
						|
uninitialized_fill------> is POD?
						|   __true_type
						|___>   fill(……)

*/

template <class ForwardIterator, class T>
inline void uninitialized_fill(ForwardIterator first, ForwardIterator last,
                               const T& x) {
  __uninitialized_fill(first, last, x, value_type(first));//判断first是不是POD类型
}

// Valid if copy construction is equivalent to assignment, and if the
//  destructor is trivial.
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());

}
/*
用x初始化[first, first+n)。也要判断是不是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));
}

// Copies [first1, last1) into [result, result + (last1 - first1)), and
//  copies [first2, last2) into
//  [result, result + (last1 - first1) + (last2 - first2)).

template <class InputIterator1, class InputIterator2, class ForwardIterator>
inline ForwardIterator
__uninitialized_copy_copy(InputIterator1 first1, InputIterator1 last1,
                          InputIterator2 first2, InputIterator2 last2,
                          ForwardIterator result) {
  ForwardIterator mid = uninitialized_copy(first1, last1, result);
  __STL_TRY {
    return uninitialized_copy(first2, last2, mid);
  }
  __STL_UNWIND(destroy(result, mid));
}

// Fills [result, mid) with x, and copies [first, last) into
//  [mid, mid + (last - first)).
template <class ForwardIterator, class T, class InputIterator>
inline ForwardIterator
__uninitialized_fill_copy(ForwardIterator result, ForwardIterator mid,
                          const T& x,
                          InputIterator first, InputIterator last) {
  uninitialized_fill(result, mid, x);
  __STL_TRY {
    return uninitialized_copy(first, last, mid);
  }
  __STL_UNWIND(destroy(result, mid));
}

// Copies [first1, last1) into [first2, first2 + (last1 - first1)), and
//  fills [first2 + (last1 - first1), last2) with x.
template <class InputIterator, class ForwardIterator, class T>
inline void
__uninitialized_copy_fill(InputIterator first1, InputIterator last1,
                          ForwardIterator first2, ForwardIterator last2,
                          const T& x) {
  ForwardIterator mid2 = uninitialized_copy(first1, last1, first2);
  __STL_TRY {
    uninitialized_fill(mid2, last2, x);
  }
  __STL_UNWIND(destroy(first2, mid2));
}

__STL_END_NAMESPACE

#endif /* __SGI_STL_INTERNAL_UNINITIALIZED_H */

// Local Variables:
// mode:C++
// End:

《STL源码剖析》---stl_uninitialized阅读笔记

时间: 2024-11-08 17:30:03

《STL源码剖析》---stl_uninitialized阅读笔记的相关文章

[转载]《STL源码剖析》阅读笔记之 迭代器及traits编程技法

本文从三方面总结迭代器   迭代器的思想   迭代器相应型别及traits思想   __type_traits思想 一 迭代器思想 迭代器的主要思想源于迭代器模式,其定义如下:提供一种方法,使之能够依序巡防某个聚合物(容 器)所含的元素,而又无需暴露该聚合物的内部表达式.可见她的主要作用便是能够降低耦合,提高代码的 模块性. STL的的中心思想在于:将数据容器和算法分开,彼此独立设计,最后再以一贴胶着剂将它们撮合 在一起,这贴胶着剂便是迭代器.迭代器的行为类似智能指针(例如标准库的auto_pt

stl源码剖析 详细学习笔记 空间配置器

//---------------------------15/04/05---------------------------- /* 空间配置器概述: 1:new操作包含两个阶段操作 1>调用::operator new配置内存(底层使用malloc来申请内存). 2>调用函数的构造函数,构造对象内容. delte和new一样,先调用析构函数,再调用::operator delete释放内存. 2:为了效率,stl把两个阶段分开来. 1>内存配置操作: alloc::allocate

stl源码剖析 详细学习笔记 算法总览

//****************************基本算法***************************** /* stl算法总览,不在stl标准规格的sgi专属算法,都以 *加以标记 算法名称              算法用途         质变                   所在文件 accumulate          元素累计            否                   <stl_numeric.h> adjacent_differenc

stl源码剖析 详细学习笔记 算法(1)

//---------------------------15/03/27---------------------------- //算法 { /* 质变算法:会改变操作对象之值 所有的stl算法都作用在由迭代器[first,last)所标示出来的区间上.质变算法 就是 运算过程会更改区间内的元素内容 非质变算法:和质变算法相反 */ /* stl算法的一般形式 1>所有的泛型算法的前两个参数都是一对迭代器,通常称为first和last,用以标示算法的操作区间 2>stl习惯采用前闭后开区间

《STL源码剖析》学习笔记(二)

STL标准模板库作为C++标准库的一部分,其组件包括:容器.算法.迭代器.仿函数.配接器.配置器. 今天来说说容器,容器主要可以分为两种:序列式容器(元素是可序的,但并非有序).关联式容器. 一.序列式容器      1.vector 1)vector和C/C++的内置数组类似,只不过array空间是静态的,vector的空间则是可以改变的,当元素个数达到空间上限时,会重新分配空间,进行复制,然后删除原空间数据. 2)vector占用一段连续的存储空间,其内部含三个指针,分别指向:该连续空间的开

《STL源码剖析》学习笔记-第6章(一) set相关算法

STL中定义的set要求元素不得重复且已经排序.而set算法要求的都是有序区间(输出也是有序的),但元素可以重复出现. STL提供了4个set相关的算法,分别是并集(union).交集(intersection).差集(difference)和对称差集(symmetric difference),这4个算法接受的set必须是有序区间,都至少接受4个参数,分别表示两个set区间.一般而言,set算法前4个参数分别表示两个区间,第五个参数表示存放结果的区间的起始位置. 1.set_union 求两个

《STL源码剖析》学习笔记-第5章 关联式容器(二)

1.set和multiset set的特性: (1)所有元素都会根据元素的键值自动被排序. (2)set是集合,它的元素的键值就是实值,实值就是键值,不允许两个元素有相同的值. (3)不可以通过set的iterator来改变元素的值,因为set的元素值就是键值,改变键值会违反元素排列的规则. (4)在客户端对set进行插入或删除操作后,之前的迭代器依然有效.当然,被删除的元素的迭代器是个例外. (5)它的底层机制是RB-tree.几乎所有的操作都只是转调用RB-tree的操作行为而已. mult

《STL源码剖析》学习笔记系列之七、八——仿函数和配接器

1. 仿函数 仿函数又名函数对象,具有函数性质的对象,就是传入一些参数,然后对参数进行某些运算,然后返回一个值.为了能够使行为类似函数,需要在类别定义中必须自定义function call 运算子operator(). 仿函数有如下几类:算术类仿函数(plus<T>.minus<T>)关系运算类仿函数(equal_to<T>.less<T>)逻辑运算类仿函数(logical_and<T>.logical_or<T>.logical_n

《STL源码剖析》读书笔记之关联式容器(1)

1.AVL树 AVL tree是指任何节点的左右子树高度相差最多1的二叉搜索树.任何节点左右子树高度最多相差1能够保证AVL树具有"对数深度"的平衡状态.在对AVL tree进行插入操作时,可能造成树平衡被破坏.根据新结点插入位置的不同,可以将平衡的破坏分成四种情况:左左,左右,右左,右右.其中左左和右右被称为外侧插入,可以采用单旋转操作调制解决.而左右和右左则称为内侧插入,可以采用双旋转操作调整解决. 单旋转: 双旋转: 2.RB-tree RB-tree是另外一个被广泛应用的平衡二

《STL源码剖析》读书笔记之序列式容器(3)

1.heap heap不属于STL容器组件,它是priority queue的底层实现机制. (1)push_heap算法 向堆中加入元素,首先将要加入的元素放到堆所在数组的末端,然后再对这个元素进行上溯操作,直到新堆合法为止.如下图所示: (2)pop_heap算法 pop_heap操作取走堆中的最大(小)值.根据堆的特性,堆的最大(小)值必定是堆所存数组的第一个元素.取堆的最大(小)元素时,将堆的最后一个元素和堆的第一个元素互换,然后再对第一个元素进行下溯操作,直到新堆满足堆的定义.下图给出