在學(xué)習(xí)STL中containers會(huì)發(fā)現(xiàn)C++ STL里定義了很多的容器(containers),每一個(gè)容器的第二個(gè)模板參數(shù)都是allocator類型,而且默認(rèn)參數(shù)都是allocator。但是allocator到底是什么?有什么作用呢?
接下來(lái)就圍繞著是什么和有什么作用來(lái)展開(kāi),其中最后補(bǔ)充一下如何去使用默認(rèn)的allocator。
由于本人學(xué)習(xí)尚淺,各種blog和msdn學(xué)習(xí)了幾天,依然還是不是特別理解。這是把自己的學(xué)習(xí)經(jīng)驗(yàn),進(jìn)行一次梳理和記錄。
std::allocatortemplate <class T> class allocator; // 默認(rèn)分配器
默認(rèn)分配器
所有的分配器都定義在 <memory> 頭文件中,被用于標(biāo)準(zhǔn)庫(kù)中的STL containers
如果標(biāo)準(zhǔn)容器中最后一個(gè)模板參數(shù)沒(méi)有指定,那么就是allocator默認(rèn)參數(shù)
對(duì)分配或釋放存儲(chǔ)的成員函數(shù)的調(diào)用將發(fā)生在一個(gè)總的順序中,并且每個(gè)這樣的釋放將在下一個(gè)分配(如果有的話)之前發(fā)生。
主要成員函數(shù)
返回x的地址
deallocate
原型函數(shù):
void deallocate(pointer p, size_t n);
釋放先前allocate分配的且沒(méi)有被釋放的存儲(chǔ)空間
p:指向以前使用allocator :: allocate分配的存儲(chǔ)塊的指針。
n:在調(diào)用allocator :: allocate時(shí)為這個(gè)存儲(chǔ)塊分配的元素?cái)?shù)量。
在默認(rèn)的allocator中,使用 ::operator delete進(jìn)行釋放
有關(guān)allocator的最重要的事實(shí)是它們只是為了一個(gè)目的:封裝STL容器在內(nèi)存管理上的低層細(xì)節(jié)。你不應(yīng)該在自己的代碼中直接調(diào)用 allocator 的成員函數(shù),除非正在寫(xiě)一個(gè)自己的STL容器。你不應(yīng)該試圖使用allocator來(lái)實(shí)現(xiàn)operator new[];這不是allocator該做的。 如果你不確定是否需要使用allocator,那就不要用。
基本上很少有人會(huì)自定義一個(gè)allocator。一來(lái),默認(rèn)的allocator已經(jīng)夠用了;二來(lái),確實(shí)不知道該怎么用。一般來(lái)說(shuō),我們沒(méi)有必要重新定義一個(gè)allocator。自定義的方式主要是為了提高內(nèi)存分配相關(guān)操作的性能。而STL提供的方式性能已經(jīng)足夠好了。
使用步驟:
由于allocator將內(nèi)存空間的分配和對(duì)象的構(gòu)建分離,故使用allocator分為以下幾步:
請(qǐng)認(rèn)真遵守這個(gè)順序使用,不然會(huì)無(wú)法預(yù)料的異常
( 下面該程序也可以解決無(wú)默認(rèn)參數(shù)來(lái)構(gòu)造對(duì)象數(shù)組的問(wèn)題)
//#include "CAnimal.h"#include <memory>#include <iostream>using namespace std;class Animal{public:#if 1 //即使為0,沒(méi)有默認(rèn)構(gòu)造也是可以, Animal() : num(0) { cout << "Animal constructor default" << endl; }#endif Animal(int _num) : num(_num) { cout << "Animal constructor param" << endl; } ~Animal() { cout << "Animal destructor" << endl; } void show() { cout << this->num << endl; }private: int num;};int main(){ allocator<Animal> alloc; //1. Animal *a = alloc.allocate(5); //2. //3. alloc.construct(a, 1); alloc.construct(a + 1); alloc.construct(a + 2, 3); alloc.construct(a + 3); alloc.construct(a + 4, 5); //4. a->show(); (a + 1)->show(); (a + 2)->show(); (a + 3)->show(); (a + 4)->show(); //5. for (int i = 0; i < 5; i++) { alloc.destroy(a + i); } //對(duì)象銷毀之后還可以繼續(xù)構(gòu)建,因?yàn)闃?gòu)建和內(nèi)存的分配是分離的 //6. alloc.deallocate(a, 5); cin.get(); return 0;}
通過(guò)運(yùn)行結(jié)果可以看出,無(wú)論是否有默認(rèn)構(gòu)造,allocator會(huì)選擇出最匹配的構(gòu)造函數(shù)(重載)
聯(lián)系客服