- 初始化空間的五個函數(shù)
- 構(gòu)造函數(shù) construct()
- 析構(gòu)函數(shù) destroy()
- 剩余三個底層函數(shù) 和?高層函數(shù)之間的對應(yīng)關(guān)系如下
- uninitialized_copy()? 對應(yīng) copy()
- uninitialized_fill()? 對應(yīng) fill()
- uninitialized_fill_n()? 對應(yīng) fill_n()
- 使用<memory>使用上述三個底層函數(shù)
uninitialized_copy()
template<class InputIterator,class ForwardIterator>
ForwardIterator uninitialized_copy(InputIterator first,InputIterator last,ForwardIterator result);
- uninitialized_copy() 將內(nèi)存的配置和對象的構(gòu)造行為分離開來
- 如果指向的輸出區(qū)域[result ,result+(last - first)] 內(nèi)的每一個迭代器都指向的是未經(jīng)初始化的區(qū)域,那么uninitialized_copy()會使用copy constructor,給身為輸入來源的[first , last] 范圍內(nèi)的每一個對象產(chǎn)生一個復(fù)制品,放到輸出范圍內(nèi)
- 針對輸入范圍內(nèi)的每一個迭代器i 使用construct(&*(result + (i-first)),*i) 產(chǎn)生*i的復(fù)制品,放置到輸出范圍的相對位置上
容器的全局間構(gòu)造函數(shù) 通過兩個步驟完成
- 配置內(nèi)存塊? 足以包含范圍內(nèi)的所有元素
- 使用uninitialized_copy()在這個范圍上構(gòu)造元素
注意事項
- 原子性;commit or rollback
- 要不給所有元素都全部執(zhí)行構(gòu)造函數(shù),要不不構(gòu)造任何東西,必須析構(gòu)已經(jīng)產(chǎn)生的所有元素
//如果是copy construction 等同于assignment而且destructor 是 trivial以下就會有效
//如果是POD型別 執(zhí)行的流程就會跳轉(zhuǎn)到以下函數(shù),這個是通過function template的參數(shù)推導(dǎo)機制得到的
template<class InputIterator,class ForwardIterator>
inline ForwardIterator __uninitialized_copy_aux(InputIterator first,InputIterator last,ForwardIterator result,true_type){return copy(first,last,result);//調(diào)用STL算法 copy()
}
//如果不是POD型別 執(zhí)行的流程就會轉(zhuǎn)向以下函數(shù) 這個是通過function template的參數(shù)推導(dǎo)機制得到的
template<class InputIterator,class ForwardIterator>
inline ForwardIterator __uninitialized_copy_aux(InputIterator first,InputIterator last,ForwardIterator result,false_type){ForwardIterator cur = result;//為了簡化 省略了異常處理for(; first!=last;++first,++cur){Chy::_allocate(&*cur,*first);}return cur;
}//函數(shù)的邏輯是
//首先萃取出 迭代器first的value type,然后判斷這個型別是否是POD類型
template<class InputIterator,class ForwardIterator,class T>
inline ForwardIterator __uninitizlized_copy(ForwardIterator first,ForwardIterator last,ForwardIterator result,T*){//以下使用的是__type_traits<T1>::is_POD_type is _PODtypedef typename __type_traits<T>::is_POD_type is_POD;return (__uninitialized_copy_aux(first,last,result,is_POD()));
}/** 迭代器first指向的是 輸入端的起始位置* 迭代器last指向的是 輸入端的結(jié)束位置* 迭代器result指向的是 輸出端的(初始化)的起始位置*/
template<class InputIterator,class ForwardIterator>
ForwardIterator uninitialized_copy(InputIterator first,InputIterator last,ForwardIterator result){}//針對 char* 和wchar*兩種型別 采用最有效率的做法 memmove(直接移動內(nèi)存內(nèi)存執(zhí)行復(fù)制的行為)
//偏特化設(shè)計
//針對const char*的特化版本inline char* uninitialized_copy(const char* first,const char* last,char* result){memmove(result,first,last-first);return result+(last - first);
}//針對const 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);
}
uninitialized_fill()
template<class ForwardIterator,class T>
ForwardIterator uninitialized_fill(ForwardIterator first,ForwardIterator last,const T&x);
- uninitialized_fill() 將內(nèi)存的配置和對象的構(gòu)造行為分離開來
- 如果指向的輸出區(qū)域[first,last] 內(nèi)的每一個迭代器都指向的是未經(jīng)初始化的區(qū)域,那么uninitialized_fill()會在這個范圍內(nèi)產(chǎn)生x(上述第三個參數(shù)的復(fù)制品)
- 即uninitialized_fill()會針對[first,last]范圍內(nèi)的每個迭代器i 調(diào)用construct(&*i,x),在i所指定的地方產(chǎn)生i的復(fù)制品。
注意事項
- 原子性;commit or rollback
- 要不給所有元素都全部執(zhí)行構(gòu)造函數(shù),要不不構(gòu)造任何東西,必須析構(gòu)已經(jīng)產(chǎn)生的所有元素
//如果是copy construction 等同于assignment而且destructor 是 trivial以下就會有效
//如果是POD型別 執(zhí)行的流程就會跳轉(zhuǎn)到以下函數(shù),這個是通過function template的參數(shù)推導(dǎo)機制得到的
template <class ForwardIterator,class T>
inline void __uninitialized_fill_aux(ForwardIterator first,ForwardIterator last,const T& x,true_type){fill(first,last,x);//調(diào)用STL算法 fill()
}
//如果不是POD型別 執(zhí)行的流程就會轉(zhuǎn)向以下函數(shù) 這個是通過function template的參數(shù)推導(dǎo)機制得到的
template <class ForwardIterator,class T>
inline void __uninitialized_fill_aux(ForwardIterator first,ForwardIterator last,const T& x,false_type){ForwardIterator cur = first;//為了簡化 省略了異常處理for(;cur != last;++cur){Chy::_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_fill_aux(first,last,x,is_POD());
}/** 迭代器first指向輸出端 (欲初始化空間) 起始處* 迭代器last指向的輸出端 (欲初始化空間) 結(jié)尾處 前閉后開區(qū)間* x 表示初始數(shù)值*/
template<class ForwardIterator,class T>
ForwardIterator 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>
ForwardIterator uninitialized_fill_n(ForwardIterator first,Size n,const T&x);
- uninitialized_fill_n() 將內(nèi)存的配置和對象的構(gòu)造行為分離開來
- 如果指向的輸出區(qū)域[first,first+n] 內(nèi)的每一個迭代器都指向的是未經(jīng)初始化的區(qū)域,那么uninitialized_fill()會在這個范圍內(nèi)產(chǎn)生x(上述第三個參數(shù)的復(fù)制品)
- 即uninitialized_fill()會針對[first,last]范圍內(nèi)的每個迭代器i 調(diào)用construct(&*i,x),在i所指定的地方產(chǎn)生i的復(fù)制品。
- 原子性;commit or rollback
- 要不給所有元素都全部執(zhí)行構(gòu)造函數(shù),要不不構(gòu)造任何東西,必須析構(gòu)已經(jīng)產(chǎn)生的所有元素
補充
- POD類型是指 Plain Old Data,也就是標(biāo)量類型或者傳統(tǒng)的C struct型別
- POD類型 必然具備trivial ctor/dtor/copy/assignment函數(shù)
- 因此對于POD型別采用最有效率的初值填寫手法,對于non POD型別采取最保險安全的做法
//如果是copy construction 等同于assignment而且destructor 是 trivial以下就會有效
//如果是POD型別 執(zhí)行的流程就會跳轉(zhuǎn)到以下函數(shù),這個是通過function template的參數(shù)推導(dǎo)機制得到的
template<class ForwardIterator,class Size,class T>
inline ForwardIterator __uninitizlized_fill_n_aux(ForwardIterator first,Size n,const T&x){return fill_n(first,n,x); //交給高階函數(shù)執(zhí)行
}//如果不是POD型別 執(zhí)行的流程就會轉(zhuǎn)向以下函數(shù) 這個是通過function template的參數(shù)推導(dǎo)機制得到的
template<class ForwardIterator,class Size,class T>
inline ForwardIterator __uninitizlized_fill_n_aux(ForwardIterator first,Size n,const T&x,false_type){ForwardIterator cur = first;//為了簡化 省略了異常處理for( ; n>0 ; --n,++cur){Chy::_allocate(&*cur,x);}return cur;
}//函數(shù)的邏輯是
//首先萃取出 迭代器first的value type,然后判斷這個型別是否是POD類型
template<class ForwardIterator,class Size,class T,class T1>
inline ForwardIterator __uninitizlized_fill_n(ForwardIterator first,Size n,const T&x,T1*){//以下使用的是__type_traits<T1>::is_POD_type is _PODtypedef typename __type_traits<T1>::is_POD_type is_POD;return __uninitizlized_fill_n_aux(first,n,x,is_POD());
}template<class ForwardIterator,class Size,class T>
ForwardIterator uninitialized_fill_n(ForwardIterator first,Size n,const T&x){return __uninitizlized_fill_n(first,n,x,value_type(first));//使用value_type()判斷first的value type
}
參考鏈接
- C++ STL __type_traits解析 - 知乎
總結(jié)
以上是生活随笔為你收集整理的STL源码剖析 内存基本处理工具 初始化空间的五个函数的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。