2.1 空間配置器(allocator)

空間配置器隱藏在一切組件之后茄猫。

1.1 設(shè)計(jì)一個(gè)簡(jiǎn)單的空間配置器

  • 根據(jù)STL的規(guī)范誊抛,以下是allocator的必要接口:  
    allocator::value_type
    allocator::pointer
    allocator::const_pointer
    allocator::reference
    allocator::const_reference
    allocator::size_type
    allocator::difference_type
    allocator::rebind // 一個(gè)嵌套的(nested)class template列牺。class rebind<U>擁有唯一成員other,是一個(gè)typedef拗窃,代表alloctor<U>
    allocator::allocator() // default constructor
    allocator::allocator(const allocator&) // copy constructor
    template <class U>allocator::allocator(const allocator<U>&) //泛化的default constructor
    allocator::~allocator() // default constructor
    pointer allocator::address(reference x) const // 返回某個(gè)對(duì)象的地址瞎领。a.address(x)等同于&x
    const_pointer allocator::address(const_reference x) const // 返回某個(gè)const對(duì)象的地址。a.address(x)等同于&x
    pointer allocator::allocate(size_type n, const void* = 0) // 配置空間随夸,足以存儲(chǔ)n個(gè)T對(duì)象九默。第二個(gè)參數(shù)是個(gè)提示,可能會(huì)用來(lái)增進(jìn)locality宾毒,可忽略
    void allocator::deallocate(pointer p, size_type n) // 歸還先前配置的空間
    size_type allocator::max_size() const // 返回可成功配置的最大量
    void allocator::construct(pointer p, const T& x) // 等同于new(const void*) p) T(x)
    void allocator::destroy(pointer p) // 等同于p->~T()

1.2 一個(gè)簡(jiǎn)單的allocator源代碼

// filename : qyalloc.h
#ifndef __QYALLOC__
#define __QYALLOC__

// placement new是operator new的一個(gè)重載版本驼修,只是我們很少用到它。如果你想在已經(jīng)分配的內(nèi)存中創(chuàng)建一個(gè)對(duì)象诈铛,使用new是不行的乙各。也就是說(shuō)placement new允許你在一個(gè)已經(jīng)分配好的內(nèi)存中(棧或堆中)構(gòu)造一個(gè)新的對(duì)象幢竹。原型中void*p實(shí)際上就是指向一個(gè)已經(jīng)分配好的內(nèi)存緩沖區(qū)的的首地址耳峦。
// placement new的作用就是:創(chuàng)建對(duì)象(調(diào)用該類的構(gòu)造函數(shù))但是不分配內(nèi)存,而是在已有的內(nèi)存塊上面創(chuàng)建對(duì)象妨退。用于需要反復(fù)創(chuàng)建并刪除的對(duì)象上妇萄,可以降低分配釋放內(nèi)存的性能消耗。請(qǐng)查閱placement new相關(guān)資料咬荷。
#include <new>          // placement new 要包含此文件冠句,聲明了一個(gè)void *operator new( size_t, void *p ) throw()  { return p; }
#include <cstddef>      // for ptrdiff_t, size_t
#include <cstdlib>      // for exit()
#include <climits>      // for UINT_MAX
#include <iostream>     // for cerr

namespace QY{
    // 分配空間(operator new)
    template <class T>
    inline T* _allocate(ptrdiff_t size, T*){
        std::set_new_handler(0);
        T *tmp = (T*)(::operator new((size_t)(size * sizeof(T))));
        if (tmp == 0)
        {
            std::cerr << "out of memory" << std::endl;
            exit(1);
        }
        return tmp;
    }
    
    // 回收空間(operator delete)
    template <class T>
    inline void _deallocate(T* buffer){
        ::operator delete(buffer);
    }
    
    // 在指定內(nèi)存上構(gòu)造一個(gè)對(duì)象(new(pMyClass)MyClass();)
    template <class T1, class T2>
    inline void _construct(T1* p, const T2& value){
        new(p) T1(value);       // 創(chuàng)建。placement new. 調(diào)用 ctor of T1, 即new(pMyClass)MyClass();
    }
    
    // 析構(gòu)對(duì)象
    template<class T>
    inline void _destroy(T* ptr){
        ptr->~T();      
    }
    
    // 按allocator標(biāo)準(zhǔn)幸乒,定義結(jié)構(gòu)
    template <class T>
    class allocator{
        public:
            typedef T           value_type;
            typedef T*          pointer;
            typedef const T*    const_pointer;
            typedef T&          reference;
            typedef const T&    const_reference;
            typedef size_t      size_type;
            typedef ptrdiff_t   difference_type;
            
            // 重新綁定分配器(rebind allocator of type U)
            template <class U>
            struct rebind
            {
                typedef allocator<U> other;
            };
            
            pointer allocate(size_type n, const void* hint=0){
                return _allocate((difference_type)n, (pointer)0);
            }
            
            void deallocate(pointer p, size_type n){
                _deallocate(p);
            }
            
            void construct(pointer p, const T& value){
                _construct(p, value);
            }
            
            void destroy(pointer p){
                _destroy(p);
            }
            
            pointer address(reference x){
                return (pointer)&x;
            }
            
            const_pointer address(const_reference x){
                return (const_pointer)&x;
            }
            
            size_type max_size() const{
                return size_type(UINT_MAX / sizeof(T));
            }            
    };
}   // end of namespace QY

#endif  // __QYALLOC__

1.3 使用這個(gè)allocator

#include "qyalloc.h"
#include <vector>
#include <iostream>
using namespace std;

int main(){
    int ia[5] = {0, 1, 2, 3, 4};
    unsigned int i;
    
    vector<int, QY::allocator<int> > iv(ia, ia+5);
    for(i=0; i<iv.size(); i++)
        cout << iv[i] << ' ';
    cout << endl;   
    
    return 0; 
}

1.4 SGI標(biāo)準(zhǔn)的空間配置器(std::allocator)

符合部分標(biāo)準(zhǔn)懦底,效率不佳,不建議使用罕扎。

1.5 SGI特殊的空間配置器(std::alloc)

 class Foo{ ... };
 Foo* pf = new Foo;    // 配置內(nèi)存聚唐,然后構(gòu)造對(duì)象
 delete pf;    // 將對(duì)象析構(gòu)丐重,然后釋放內(nèi)存

new: (1)調(diào)用 ::operator new 配置內(nèi)存;
     (2)調(diào)用 Foo::Foo() 構(gòu)造對(duì)象內(nèi)容杆查。
  delete: (1)調(diào)用 Foo::~Foo() 將對(duì)象析構(gòu)扮惦;
     (2)調(diào)用 ::operator delete 釋放內(nèi)存。
  為了精密分工亲桦,STL allocator 將兩階段操作區(qū)分開(kāi)來(lái)崖蜜。
  alloc::allocate()負(fù)責(zé)內(nèi)存配置操作;
  alloc::deallocate()負(fù)責(zé)內(nèi)存釋放操作客峭;
  ::construct()負(fù)責(zé)對(duì)象構(gòu)造操作豫领;
  ::destroy()負(fù)責(zé)對(duì)象析構(gòu)操作。


1.6 構(gòu)造和析構(gòu)基本工具:construct() 和 destroy()

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末舔琅,一起剝皮案震驚了整個(gè)濱河市等恐,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌备蚓,老刑警劉巖课蔬,帶你破解...
    沈念sama閱讀 219,490評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異星著,居然都是意外死亡购笆,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,581評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén)虚循,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)同欠,“玉大人,你說(shuō)我怎么就攤上這事横缔∑趟欤” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,830評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵茎刚,是天一觀的道長(zhǎng)襟锐。 經(jīng)常有香客問(wèn)我,道長(zhǎng)膛锭,這世上最難降的妖魔是什么粮坞? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,957評(píng)論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮初狰,結(jié)果婚禮上莫杈,老公的妹妹穿的比我還像新娘。我一直安慰自己奢入,他們只是感情好筝闹,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,974評(píng)論 6 393
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著,像睡著了一般关顷。 火紅的嫁衣襯著肌膚如雪糊秆。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 51,754評(píng)論 1 307
  • 那天议双,我揣著相機(jī)與錄音痘番,去河邊找鬼。 笑死聋伦,一個(gè)胖子當(dāng)著我的面吹牛夫偶,可吹牛的內(nèi)容都是我干的界睁。 我是一名探鬼主播觉增,決...
    沈念sama閱讀 40,464評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼翻斟!你這毒婦竟也來(lái)了逾礁?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 39,357評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤访惜,失蹤者是張志新(化名)和其女友劉穎嘹履,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體债热,經(jīng)...
    沈念sama閱讀 45,847評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡砾嫉,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,995評(píng)論 3 338
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了窒篱。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片焕刮。...
    茶點(diǎn)故事閱讀 40,137評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖墙杯,靈堂內(nèi)的尸體忽然破棺而出配并,到底是詐尸還是另有隱情,我是刑警寧澤高镐,帶...
    沈念sama閱讀 35,819評(píng)論 5 346
  • 正文 年R本政府宣布溉旋,位于F島的核電站,受9級(jí)特大地震影響嫉髓,放射性物質(zhì)發(fā)生泄漏观腊。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,482評(píng)論 3 331
  • 文/蒙蒙 一算行、第九天 我趴在偏房一處隱蔽的房頂上張望梧油。 院中可真熱鬧,春花似錦纱意、人聲如沸婶溯。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,023評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)迄委。三九已至褐筛,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間叙身,已是汗流浹背渔扎。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,149評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留信轿,地道東北人晃痴。 一個(gè)月前我還...
    沈念sama閱讀 48,409評(píng)論 3 373
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像财忽,于是被迫代替她去往敵國(guó)和親倘核。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,086評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容

  • Spring Cloud為開(kāi)發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見(jiàn)模式的工具(例如配置管理即彪,服務(wù)發(fā)現(xiàn)紧唱,斷路器,智...
    卡卡羅2017閱讀 134,672評(píng)論 18 139
  • 在iOS開(kāi)發(fā)過(guò)程中, 我們可能會(huì)碰到一些系統(tǒng)方法棄用, weak隶校、循環(huán)引用漏益、不能執(zhí)行之類的警告。 有代碼潔癖的孩子...
    磁針石閱讀 11,405評(píng)論 0 16
  • 接著上節(jié) condition_varible 深胳,本節(jié)主要介紹future的內(nèi)容绰疤,練習(xí)代碼地址。本文參考http:/...
    jorion閱讀 14,795評(píng)論 1 5
  • 所有的編譯警告的名稱:參見(jiàn)網(wǎng)址:http://fuckingclangwarnings.com注意這篇文章的創(chuàng)建時(shí)...
    zhangyin閱讀 10,724評(píng)論 0 53
  • 如圖舞终,所謂的這整個(gè)安排為哪些人作出的轻庆?這個(gè)問(wèn)題,我自己的初步理解是為了給那些不堅(jiān)持自己的路权埠,不堅(jiān)守自己靈魂的人作出...
    布丁香閱讀 1,513評(píng)論 2 10