日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

一步一步写STL:空间配置器(1)

發(fā)布時(shí)間:2025/3/15 编程问答 20 豆豆
生活随笔 收集整理的這篇文章主要介紹了 一步一步写STL:空间配置器(1) 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
侯捷說:追蹤一流程序,并從中吸取養(yǎng)分,模仿著他寫的程序,比那些自以為靠自己努力寫出來的下三流程序價(jià)值高得多,至少我這么認(rèn)為——世界上99.999%的程序,在STL面前都是下三流水平!

?

侯捷老師這句話對(duì)STL的評(píng)價(jià)太高了,以前只是熟練使用STL,知道一點(diǎn)原理,受他的影響,最終還是決定研究STL的源碼,收益頗豐,還是把這個(gè)過程記錄下來,并想著借助標(biāo)準(zhǔn)庫(kù)的原理,自己寫一個(gè)完整的仿STL,我覺得這是一個(gè)很大的工程,因?yàn)樯婕暗礁呒?jí)數(shù)據(jù)結(jié)構(gòu),強(qiáng)大的算法,泛型編程思維,STL的掌握,強(qiáng)大的C++編碼水平,層次復(fù)雜的繼承,型別萃取技術(shù),相信這個(gè)過程會(huì)收益頗豐!畢竟我才大二,時(shí)間一大把,我想在我本科期間,做完這一個(gè)工程,也無憾了!

?

下圖就是STL的層次分布圖,當(dāng)然還缺少一些組件,比如數(shù)值處理,pair對(duì)組,string,智能指針以及valarray數(shù)組等等,其中實(shí)現(xiàn)的難點(diǎn)主要集中在幾個(gè)地方,分別是map紅黑樹的實(shí)現(xiàn),heap算法體系,函數(shù)配接器,流迭代器。尤其是函數(shù)配接器,他的內(nèi)部實(shí)現(xiàn)簡(jiǎn)直是窮盡一切頂尖技巧,令人嘆為觀止,我先從最左邊的內(nèi)存分配器開始,因?yàn)樗撬械暮诵?#xff01;

?

?

首先STL的內(nèi)存分配器(空間配置器)在標(biāo)準(zhǔn)庫(kù)中充當(dāng)了異常重要的角色,所有的內(nèi)存分配,管理,釋放都是由他控制,SGI的設(shè)計(jì)理念就是把內(nèi)存管理這一塊紅燈區(qū)抽離出來,作為模版參數(shù)傳遞進(jìn)去每個(gè)容器,

比如在vector:

template<class T,class Alloc<T> = allocator<T> >

class vector.........

他使用的是內(nèi)置的默認(rèn)內(nèi)存分配器,在上圖中我們看到有兩個(gè)分配器,這是SGI STL中的高級(jí)之處,實(shí)作了多級(jí)內(nèi)存分配,利用內(nèi)存池實(shí)現(xiàn)效率上的優(yōu)化,同時(shí)也減少了內(nèi)存碎片的可能性。

在這之前需要知道兩個(gè)全局函數(shù) ::operator new 和 ::operator delete ,注意不要把他們和一般的new delete混為一談,我們的運(yùn)算符new在分配內(nèi)存的時(shí)候同時(shí)調(diào)用對(duì)象的構(gòu)造函數(shù)初始化內(nèi)存,而::operator new只是分配內(nèi)存,并不調(diào)用構(gòu)造函數(shù),這是實(shí)現(xiàn)一塊無初始化內(nèi)存池的關(guān)鍵點(diǎn),同理delete。

另外還需要了解placement new運(yùn)算符,他是定位運(yùn)算符,并不分配內(nèi)存,只是定位到某一已分配區(qū)域!

這里我們先實(shí)現(xiàn)一個(gè)能跟標(biāo)準(zhǔn)容器接口的分配器類,他并不高明,但是體現(xiàn)了標(biāo)準(zhǔn)分配器的必要特性,其實(shí)從某個(gè)角度說屬于SGI版本的一級(jí)分配器:

[cpp] view plaincopyprint?
  • template<class?_Ty>??
  • ????struct?Allocator_base??
  • ????{???//配置器基類??
  • ????typedef?_Ty?value_type;??
  • ????};??
  • ??
  • template<class?_Ty>??
  • ????struct?Allocator_base<const?_Ty>??
  • ????{???//配置器特化于const的基類??
  • ????typedef?_Ty?value_type;??
  • ????};??
  • ??
  • template<class?_Ty>??
  • class?Allocator??
  • ????????:public?Allocator_base<_Ty>??
  • {??
  • public:??
  • ????//配置器內(nèi)部型別??
  • ????typedef?typename?std::size_t?size_type;??
  • ????typedef?typename?std::ptrdiff_t?difference_type;??
  • ????typedef?_Ty*?pointer;??
  • ????typedef?const?_Ty*?const_pointer;??
  • ????typedef?_Ty&?reference;??
  • ????typedef?const?_Ty&?const_reference;??
  • ????typedef?Allocator_base<_Ty>?_Mybase;??
  • ????typedef?typename?_Mybase::value_type?value_type;??
  • ??
  • ????//配置器型別轉(zhuǎn)換??
  • ????template<class?_other>??
  • ????struct?rebind??
  • ????{??
  • ????????typedef?Allocator<_other>?other;??
  • ????};??
  • ??
  • ????//地址函數(shù)定義??
  • ????pointer?address(reference?value)const{??
  • ????????return?&value;??
  • ????}??
  • ????const_pointer?address(const_reference?value)const{??
  • ????????return?(const_pointer)&value:??
  • ????}??
  • ??
  • ????//默認(rèn)構(gòu)造函數(shù)?什么都不干??
  • ????Allocator()?throw()?{}??
  • ????//默認(rèn)復(fù)制構(gòu)造???
  • ????Allocator(const?Allocator?&)throw()?{}??
  • ????//不同配置器的復(fù)制構(gòu)造??
  • ????template<class?_otherAll>??
  • ????Allocator(const?Allocator<_otherAll>?&)throw()?{}??
  • ??
  • ????//析構(gòu)函數(shù)??
  • ????~Allocator()throw()?{}??
  • ??????
  • ????//返回能分配的最大內(nèi)存??
  • ????size_type?max_size()const?throw()??
  • ????{???//借助數(shù)值函數(shù)??
  • ????????numeric_limit<size_type>::max()?/sizeof(_Ty);??
  • ????}??
  • ????//分配未構(gòu)造的內(nèi)存待用??
  • ????pointer?allocate(size_type?num,??
  • ????????typename?Allocator<void>::const_pointer?hint=?0)??
  • ????{??
  • ????????return?(pointer)(::operator?new(num?*?sizeof(_Ty))?);??
  • ????}??
  • ????//在內(nèi)存中構(gòu)造對(duì)象??
  • ????void?construct(pointer?p,const_reference?value)??
  • ????{??
  • ????????new(p)?_Ty(value);??
  • ????}??
  • ????//析構(gòu)內(nèi)存中的對(duì)象??
  • ????void?destroy(pointer?p)??
  • ????{??
  • ????????p->~_Ty();??
  • ????}??
  • ??
  • ????void?deallocate(?pointer?p,?size_type?size?)??
  • ????{??
  • ????????::operator?delete(p);??
  • ????}??
  • ????//為了跟標(biāo)準(zhǔn)配置器接軌,這里只能返回true,下一個(gè)只能返回false??
  • ????bool?operator==(Allocator?const&?a)?const???
  • ????{?return?true;?}??
  • ??
  • ????bool?operator!=(Allocator?const&?a)?const???
  • ????{?return?!operator==(a);?}??
  • };??
  • ??
  • ??
  • //allocator模版特化于類型void的類??
  • template<>?class?Allocator<void>??
  • {??
  • public:??
  • ????typedef?void?_Ty;??
  • ????typedef?_Ty*?pointer;??
  • ????typedef?const?_Ty*?const_pointer;??
  • ????typedef?_Ty?value_type;??
  • ??
  • ????template<class?_other>??
  • ????struct?rebind??
  • ????{??
  • ????????typedef?Allocator<_other>?other;???
  • ????};??
  • ??
  • ????Allocator()throw()???
  • ????{?//還是一樣,什么都不干??
  • ????}??
  • ??
  • ????Allocator(const?Allocator<_Ty>&?)throw()??
  • ????{?//復(fù)制構(gòu)造,什么都不干??
  • ????}??
  • ??
  • ????template<class?_Other>??
  • ????????Allocator(const?Allocator<_Other>&)?throw()??
  • ????????{?????
  • ????????}??
  • ????template<class?_Other>??
  • ????????Allocator<_Ty>&?operator=(const?Allocator<_Other>&)??
  • ????????{?????
  • ????????return?(*this);??
  • ????????}??
  • ??
  • };??
  • template<class _Ty>struct Allocator_base{ //配置器基類typedef _Ty value_type;};template<class _Ty>struct Allocator_base<const _Ty>{ //配置器特化于const的基類typedef _Ty value_type;};template<class _Ty> class Allocator:public Allocator_base<_Ty> { public://配置器內(nèi)部型別typedef typename std::size_t size_type;typedef typename std::ptrdiff_t difference_type;typedef _Ty* pointer;typedef const _Ty* const_pointer;typedef _Ty& reference;typedef const _Ty& const_reference;typedef Allocator_base<_Ty> _Mybase;typedef typename _Mybase::value_type value_type;//配置器型別轉(zhuǎn)換template<class _other>struct rebind{typedef Allocator<_other> other;};//地址函數(shù)定義pointer address(reference value)const{return &value;}const_pointer address(const_reference value)const{return (const_pointer)&value:}//默認(rèn)構(gòu)造函數(shù) 什么都不干Allocator() throw() {}//默認(rèn)復(fù)制構(gòu)造 Allocator(const Allocator &)throw() {}//不同配置器的復(fù)制構(gòu)造template<class _otherAll>Allocator(const Allocator<_otherAll> &)throw() {}//析構(gòu)函數(shù)~Allocator()throw() {}//返回能分配的最大內(nèi)存size_type max_size()const throw(){ //借助數(shù)值函數(shù)numeric_limit<size_type>::max() /sizeof(_Ty);}//分配未構(gòu)造的內(nèi)存待用pointer allocate(size_type num,typename Allocator<void>::const_pointer hint= 0){return (pointer)(::operator new(num * sizeof(_Ty)) );}//在內(nèi)存中構(gòu)造對(duì)象void construct(pointer p,const_reference value){new(p) _Ty(value);}//析構(gòu)內(nèi)存中的對(duì)象void destroy(pointer p){p->~_Ty();}void deallocate( pointer p, size_type size ){::operator delete(p);}//為了跟標(biāo)準(zhǔn)配置器接軌,這里只能返回true,下一個(gè)只能返回falsebool operator==(Allocator const& a) const { return true; }bool operator!=(Allocator const& a) const { return !operator==(a); } };//allocator模版特化于類型void的類 template<> class Allocator<void> { public:typedef void _Ty;typedef _Ty* pointer;typedef const _Ty* const_pointer;typedef _Ty value_type;template<class _other>struct rebind{typedef Allocator<_other> other; };Allocator()throw() { //還是一樣,什么都不干}Allocator(const Allocator<_Ty>& )throw(){ //復(fù)制構(gòu)造,什么都不干}template<class _Other>Allocator(const Allocator<_Other>&) throw(){ }template<class _Other>Allocator<_Ty>& operator=(const Allocator<_Other>&){ return (*this);}};


    最開始是兩個(gè)基類,這兩個(gè)基類沒有任何成員,只有一個(gè)內(nèi)置型別,這兩個(gè)基類不是必須的,可以略過,只是體現(xiàn)一種好的設(shè)計(jì)而已,最后一個(gè)類是模版特化了一個(gè)void類型,這樣做也只是為了使用void的時(shí)候不發(fā)生未定義行為,從這一點(diǎn)可以看到STL對(duì)各種可能的情況都做了充分的預(yù)料,我們主要來看Allocator類!

    剛開始定義了一對(duì)typedef,這是為分配器類定義一堆內(nèi)置型別,其實(shí)也可以不定義啊,只不過在STL中都這樣定義,構(gòu)建出一種統(tǒng)一的類型型別,方便管理和可讀性

    接下來的

    template<class _other>

    struct rebind

    {

    ???? typedef Allocator<_other> other;

    };

    這是一個(gè)分配器轉(zhuǎn)換方式,可以方便的轉(zhuǎn)換為為另一種類型服務(wù)的分配器,比如說我們構(gòu)造的是T類,如果需要構(gòu)造T*的時(shí)候,可以這樣使用

    Allocator<T>::rebind<T*>::other? pAllocator;

    這樣pAllocator就是一個(gè)為T*服務(wù)的分配器,具體參考《STL標(biāo)準(zhǔn)程序庫(kù)》!

    ?

    該類接下來的函數(shù)都是標(biāo)準(zhǔn)接口必須的,不能少任何一個(gè),其中有變動(dòng)的是這四個(gè) allocate?? deallocate?? destory? construct

    allocate函數(shù)分配一片連續(xù)的未被構(gòu)造的空間備用,

    deallocate??函數(shù)釋放空間

    construct函數(shù)調(diào)用布局new,同時(shí)調(diào)用構(gòu)造函數(shù),對(duì)象被new定位在指定位置

    destory?函數(shù)調(diào)用析構(gòu)函數(shù),

    之所以說這幾個(gè)函數(shù)可變性比較大,我舉個(gè)例子,假如我們做一個(gè)學(xué)生成績(jī)管理系統(tǒng),當(dāng)然需要構(gòu)造學(xué)生類,也就是需要從數(shù)據(jù)庫(kù)獲得數(shù)據(jù)來初始化學(xué)生對(duì)象,那么你就可以在construct里面內(nèi)嵌SQL語句,在你盛裝學(xué)生對(duì)象的容器中,獲得的數(shù)據(jù)來源不是從鍵盤輸入(參數(shù)傳入),而是自動(dòng)的從數(shù)據(jù)庫(kù)獲取過來,這樣豈不是很方便!同理其他幾個(gè)函數(shù),

    這個(gè)分配器還是很簡(jiǎn)單的,就只需要注意那幾點(diǎn),所以我們?cè)趯懽约旱姆峙淦飨M蜆?biāo)準(zhǔn)容器接口時(shí),需要注意這幾點(diǎn)

    ?

    以后還會(huì)使用這個(gè)分配器,直接拿來當(dāng)作SGI STL版本的一級(jí)分配器,至于二級(jí)分配器,下一節(jié)在寫!

    到此我們可以寫個(gè)小程序測(cè)試一下了:

    [cpp] view plaincopyprint?
  • #include?<iostream>??
  • #include?<list>??
  • #include?<vector>??
  • #include?<algorithm>??
  • #include?"allocator.h"??
  • using?namespace?std;??
  • ??
  • int?_tmain(int?argc,?_TCHAR*?argv[])??
  • {??
  • ????std::vector<double,Allocator<double>?>?vec_double;??
  • ????std::list<int,Allocator<int>?>?list_int;??
  • ????for(int?i=0;i<60;i++)??
  • ????{??
  • ????????list_int.push_back(i);??
  • ????????vec_double.push_back(?double(i)/3?);??
  • ????}??
  • ??????
  • ????list<int,Allocator<int>?>::iterator?it?=?list_int.begin();??
  • ????vector<double,Allocator<double>?>::iterator?io?=?vec_double.begin();??
  • ??
  • ????cout<<"list?test:"<<endl;??
  • ????for(;?it!=?list_int.end();++it)??
  • ????????cout<<*it<<"?";??
  • ????cout<<endl<<endl;??
  • ??
  • ????cout<<"vector?test:"<<endl;??
  • ????for(;io!=?vec_double.end();++io)??
  • ????????cout<<*io<<"?";??
  • ??
  • ????system("pause");??
  • ????return?0;??
  • }??
  • #include <iostream> #include <list> #include <vector> #include <algorithm> #include "allocator.h" using namespace std;int _tmain(int argc, _TCHAR* argv[]) {std::vector<double,Allocator<double> > vec_double;std::list<int,Allocator<int> > list_int;for(int i=0;i<60;i++){list_int.push_back(i);vec_double.push_back( double(i)/3 );}list<int,Allocator<int> >::iterator it = list_int.begin();vector<double,Allocator<double> >::iterator io = vec_double.begin();cout<<"list test:"<<endl;for(; it!= list_int.end();++it)cout<<*it<<" ";cout<<endl<<endl;cout<<"vector test:"<<endl;for(;io!= vec_double.end();++io)cout<<*io<<" ";system("pause");return 0; }



    ?

    ?

    ?

    ?

    ?

    ?

    總結(jié)

    以上是生活随笔為你收集整理的一步一步写STL:空间配置器(1)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。

    主站蜘蛛池模板: 亚洲乱码国产一区三区 | 欧美黑吊大战白妞 | 男人的天堂aa | 国产中文字幕乱人伦在线观看 | 国产午夜在线视频 | 日韩欧美xxxx | 日韩二区 | 成年人在线免费观看 | 国产精选久久久 | 中国18videosex极品 | 91丨国产 | 女人喂男人奶水做爰视频 | 日日夜夜噜 | 欧美男女交配视频 | 国产天堂在线 | 夜夜添无码一区二区三区 | 久久毛片基地 | 风韵丰满熟妇啪啪区老熟熟女 | 国产精品揄拍100视频 | 91视频播放 | av女优一区 | 国产情侣第一页 | 久久久久久欧美精品se一二三四 | 欧美日韩首页 | 亚洲视频成人 | 伊人精品视频在线观看 | 亚洲成人激情在线 | 日本a级c片免费看三区 | 亚洲资源网 | 欧美精品videos | 中文字幕亚洲天堂 | 男人天堂aaa | 国产91丝袜在线播放0 | 天堂网在线视频 | 国产第四页 | 婷婷中文字幕 | 激情视频网站 | 久久伊人超碰 | 国产精品无码粉嫩小泬 | 一本色道久久综合狠狠躁的推荐 | 国产精品一线天 | 中文字幕国产一区 | 拍真实国产伦偷精品 | 麻豆影视av | 免看一级片 | 美女被艹视频网站 | 亚洲精品天堂在线 | 亚洲福利视频网 | 一本大道熟女人妻中文字幕在线 | 美女自卫网站 | 色爱区综合 | 久久精品无码一区 | 视频在线观看一区二区三区 | 黄页网站免费观看 | 国产精品无码久久久久 | 久久青草免费视频 | 国产强被迫伦姧在线观看无码 | 免费观看黄网站 | 午夜一区二区三区在线 | 亚洲成人精品av | 亚洲一区久久 | 国产人妖一区二区 | 午夜做爰xxxⅹ性高湖视频美国 | 欧美顶级黄色大片免费 | 免费黄色在线观看 | 国产精品v亚洲精品v日韩精品 | 一区二区三区四区影院 | 黄网在线播放 | 黄色电影在线视频 | 性免费视频 | 中国老头性行为xxxx | 亚色一区 | 国产一区视频观看 | 日韩中文欧美 | av手机 | 好吊色视频一区二区 | 久久538| 亚洲欧美一二三 | 88久久精品无码一区二区毛片 | 久久久精品人妻一区二区三区 | 日韩美女视频在线 | 成人91 | 久久国产精品区 | 五月天婷婷在线视频 | 波多野结衣视频免费观看 | jizz另类| 欧美午夜性春猛交 | 亚洲视频一区二区 | 欧美色欧美 | 潘金莲裸体一级淫片视频 | 丰满岳乱妇国产精品一区 | 婷婷的五月 | 麻豆精品久久久 | 午夜国产福利视频 | 女人扒开屁股让我添 | 欧美激情综合网 | 香蕉视频在线免费播放 | 日本中文字幕有码 | 国产av日韩一区二区三区精品 |