allocator类编程实验
allocator類編程實驗
- 基本知識
- allocator
- uninitialized_copy、uninitialized_fill等函數(shù)
- 示例程序
- 示例代碼
- usealloc.cpp
- usealloc2.cpp
本文是本人大一期間在校學習C++課程時所撰寫的實驗報告的摘錄,由于剛上大學,剛接觸計算機編程方面的相關知識,故可能會有很多不足甚至錯誤的地方,還請各位看官指出及糾正。
本文所涉及到的“教材”指:
電子工業(yè)出版社《C++ Primary中文版(第5版)》
如需轉(zhuǎn)載或引用請標明出處。
基本知識
allocator
當分配一大塊內(nèi)存時,我們通常計劃在這塊內(nèi)存上按需構(gòu)造對象。在此情況下,我們只在真正需要時才執(zhí)行對象的構(gòu)建操作。
標準庫類型allocator可以幫助我們將內(nèi)存分配和對象構(gòu)造分離開來,它分配的內(nèi)存是原始的、未構(gòu)造的,它定義在頭文件memory中。下面是allocator的一些相關操作:
allocator<T> a //定義一個名為a的allocator對象,可以為類型為T的對象分配內(nèi)存 a.allocate (n) //分配一段原始的、未構(gòu)造的內(nèi)存,保存n個類型為T的對象 a.destroy (p) //p為T*類型的指針, 對p指向的對象執(zhí)行相應的析構(gòu)函數(shù) a.deallocate (p, n) //釋放從T*指針p中地址開始的內(nèi)存,其中n必須是p創(chuàng)建時的大小。在調(diào)用該函數(shù)前,必須對該內(nèi)存中的每個對象調(diào)用destroy a.construct (p, args) //T*指針指向一塊原始內(nèi)存,arg被傳遞給類型為T的構(gòu)造函數(shù),在p所指內(nèi)存中構(gòu)造對象定義一個allocator時必須指明其可以分配的對象類型。當一個allocator對象分配內(nèi)存時,它會根據(jù)給定的對象類型來確定恰當?shù)膬?nèi)存大小和對其位置:
allocator<string> alloc; //alloc可以分配string string *p = alloc.allocate(n); //分配n個未初始化的stringallocator分配的內(nèi)存是未構(gòu)造的,我們按需在此內(nèi)存中構(gòu)造對象。construct成員函數(shù)接受一個指針和零個或多個額外參數(shù),在給定位置構(gòu)造一個元素。額外參數(shù)用來初始化構(gòu)造的對象。例如:
alloc.construct(q++); //*q為空字符串 alloc.construct(q++, 3, 'c'); //*q為ccc alloc.construct(q++, "hi") //*q為hi在我們用完對象后,必須對每個構(gòu)造的對象調(diào)用destroy來銷毀它們。一旦元素被銷毀后,就可以重新使用這部分內(nèi)存來保存其他string,也可以將其歸還給系統(tǒng)。釋放內(nèi)存通過調(diào)用deallocate來完成。其中的指針參數(shù)必須指向allocate分配的內(nèi)存,而且傳遞給deallocate的大小參數(shù)也必須和調(diào)用allocated分配內(nèi)存時提供的大小參數(shù)具有一樣的值。
uninitialized_copy、uninitialized_fill等函數(shù)
標準庫還為allocator類定義了兩個伴隨算法,可以在未初始化內(nèi)存中創(chuàng)建對象,這些函數(shù)定義在memory頭文件中,描述如下:
uninitialized_copy (b, e, b2) //從迭代器b和e指定的范圍中拷貝元素到迭代器b2指定的未構(gòu)造的原始內(nèi)存中 uninitialized_copy_n (b, n, b2) //從迭代器b指定的位置開始,拷貝n個元素到b2開始的內(nèi)存中 uninitialized_fill (b, e, t) //從迭代器b和e指定的原始內(nèi)存范圍中創(chuàng)建對象,對象的值均為t的拷貝 uninitialized_fill_n (b, n, t) //從迭代器b指定的位置開始創(chuàng)建n個對象,對象的值均為t的拷貝uninitialized_copy接受三個迭代器參數(shù)。前兩個表示輸入序列,第三個表示這些元素要拷貝到的目的空間。傳遞給uninitialized_copy的目的位置迭代器必須指向未構(gòu)造的內(nèi)存。返回遞增后的目的位置迭代器,因此,一次uninitialized_copy調(diào)用會返回一個指針,指向最后構(gòu)造的元素之后的位置。
uninitialized_fill則更像是填充函數(shù)。
這些函數(shù)的目標地址都必須足夠大,能容納要創(chuàng)建或拷貝的對象。
示例程序
usealloc.cpp主要展示了allocator的相關用法及使用數(shù)組和allocator的區(qū)別,usealloc2.cpp主要展示了使用uninitialized_copy和uninitialized_fill使用方法。
示例代碼
usealloc.cpp
#include <string> using std::string; #include <memory> //使用allocator using std::allocator;#include <cstddef> //使用size_t using std::size_t; #include <iostream> using std::cout; using std::endl; #include <fstream> //使用文件流 using std::ifstream;int main() {const size_t n = 100;allocator<string> alloc; //alloc是一個可以分配string的對象string *p = alloc.allocate(n); //p指向alloc分配的n個沒有初始化的的string的內(nèi)存空間的開始string *q = p; //q指向最后構(gòu)造的元素之后的位置alloc.construct(q++, string()); //在q指向的位置(即p)處,初始化一個空string,再遞增q的位置cout << *(q - 1) << endl; //輸出上面的stringalloc.construct(q++, string(10, 'c')); //初始化下一個string,由十個‘c’組成cout << *(q - 1) << endl; //輸出上面的stringalloc.construct(q++, string("hi")); //初始化下一個string,是“hi”cout << *(q - 1) << endl; //輸出上面的string cout << *p << endl; //因為p指向第一個字符串的位置,所以可以解引用輸出while (q != p) //析構(gòu)上述初始化的stringalloc.destroy(--q); //因為q指向尾后,所以先遞減q,再對其指向的string執(zhí)行對應的析構(gòu)函數(shù)alloc.deallocate(p, n); //回收之前分配的空間p = alloc.allocate(n); //重新分配n個沒有初始化的的string的內(nèi)存空間string s; //s用于臨時存儲讀入q = p; //q指向上面分配空間的第一個stringifstream in("data/storyDataFile"); //聲明一個文件輸入流in,讀取目錄下data/storyDataFile的內(nèi)容while (in >> s && q != p + n)alloc.construct(q++, s); //當有讀入一個string時才初始化一個stringsize_t size = q - p; //指示有多少個string初始化cout << "read " << size << " strings" << endl;for (q = p + size - 1; q != p; --q)alloc.destroy(q); //析構(gòu)每一個已初始化的stringalloc.deallocate(p, n); //回收之前分配的空間//使用數(shù)組代替上面的實現(xiàn)in.close(); //關閉文件輸入流inin.open("data/storyDataFile"); //重新打開文件輸入流inp = new string[n]; //初始化n個string,構(gòu)成數(shù)組,p指向第一個的位置q = p;while (in >> s && q != p + n)*q++ = s; //對q指向的string重新賦值size = q - p; //指示有多少個string被重新賦值cout << "read " << size << " strings" << endl;delete[] p; //用delete[]釋放數(shù)組system("pause");return 0; }運行結(jié)果:
創(chuàng)建data/storyDataFile文件:
運行程序,結(jié)果如下:
說明in文件讀入流以任意空白作為是否讀取一個string的判斷依據(jù)。
usealloc2.cpp
#include <cstddef> using std::size_t;#include <string> using std::string; #include <vector> using std::vector; #include <memory> //使用allocator、uninitialized_copy等 using std::uninitialized_copy; using std::allocator; using std::uninitialized_fill_n;#include <iostream> using std::cout; using std::endl;int main() {int temp[] = {1,2,3,4,5,6,7,8,9};vector<int> vi(temp, temp + sizeof(temp)/sizeof(*temp));allocator<int> alloc;int *p = alloc.allocate(vi.size() * 2); //alloc所占有的空間是vi的兩倍,其被p指向int *q = uninitialized_copy(vi.begin(), vi.end(), p); //將vi中的元素都拷貝到alloc中,q指向尾后元素 uninitialized_fill_n(q, vi.size(), 42); //將剩下的空間都初始化為42for (size_t i = 0; i != vi.size(); ++i) //輸出前一半元素cout << *(p + i) << " ";cout << endl;for (size_t i = 0; i != vi.size(); ++i) //輸出后一半元素cout << *(q + i) << " ";cout << endl;alloc.deallocate(p, vi.size() * 2);system("pause");return 0; }運行結(jié)果:
總結(jié)
以上是生活随笔為你收集整理的allocator类编程实验的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: weak_ptr指针编程实验
- 下一篇: 文本查询编程实验