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