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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

allocator类编程实验

發布時間:2024/4/18 编程问答 47 豆豆
生活随笔 收集整理的這篇文章主要介紹了 allocator类编程实验 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

allocator類編程實驗

    • 基本知識
      • allocator
      • uninitialized_copy、uninitialized_fill等函數
      • 示例程序
    • 示例代碼
      • usealloc.cpp
      • usealloc2.cpp

本文是本人大一期間在校學習C++課程時所撰寫的實驗報告的摘錄,由于剛上大學,剛接觸計算機編程方面的相關知識,故可能會有很多不足甚至錯誤的地方,還請各位看官指出及糾正。
本文所涉及到的“教材”指:
電子工業出版社《C++ Primary中文版(第5版)》
如需轉載或引用請標明出處。

基本知識

allocator

當分配一大塊內存時,我們通常計劃在這塊內存上按需構造對象。在此情況下,我們只在真正需要時才執行對象的構建操作。

標準庫類型allocator可以幫助我們將內存分配和對象構造分離開來,它分配的內存是原始的、未構造的,它定義在頭文件memory中。下面是allocator的一些相關操作:

allocator<T> a //定義一個名為a的allocator對象,可以為類型為T的對象分配內存 a.allocate (n) //分配一段原始的、未構造的內存,保存n個類型為T的對象 a.destroy (p) //p為T*類型的指針, 對p指向的對象執行相應的析構函數 a.deallocate (p, n) //釋放從T*指針p中地址開始的內存,其中n必須是p創建時的大小。在調用該函數前,必須對該內存中的每個對象調用destroy a.construct (p, args) //T*指針指向一塊原始內存,arg被傳遞給類型為T的構造函數,在p所指內存中構造對象

定義一個allocator時必須指明其可以分配的對象類型。當一個allocator對象分配內存時,它會根據給定的對象類型來確定恰當的內存大小和對其位置:

allocator<string> alloc; //alloc可以分配string string *p = alloc.allocate(n); //分配n個未初始化的string

allocator分配的內存是未構造的,我們按需在此內存中構造對象。construct成員函數接受一個指針和零個或多個額外參數,在給定位置構造一個元素。額外參數用來初始化構造的對象。例如:

alloc.construct(q++); //*q為空字符串 alloc.construct(q++, 3, 'c'); //*q為ccc alloc.construct(q++, "hi") //*q為hi

在我們用完對象后,必須對每個構造的對象調用destroy來銷毀它們。一旦元素被銷毀后,就可以重新使用這部分內存來保存其他string,也可以將其歸還給系統。釋放內存通過調用deallocate來完成。其中的指針參數必須指向allocate分配的內存,而且傳遞給deallocate的大小參數也必須和調用allocated分配內存時提供的大小參數具有一樣的值。

uninitialized_copy、uninitialized_fill等函數

標準庫還為allocator類定義了兩個伴隨算法,可以在未初始化內存中創建對象,這些函數定義在memory頭文件中,描述如下:

uninitialized_copy (b, e, b2) //從迭代器b和e指定的范圍中拷貝元素到迭代器b2指定的未構造的原始內存中 uninitialized_copy_n (b, n, b2) //從迭代器b指定的位置開始,拷貝n個元素到b2開始的內存中 uninitialized_fill (b, e, t) //從迭代器b和e指定的原始內存范圍中創建對象,對象的值均為t的拷貝 uninitialized_fill_n (b, n, t) //從迭代器b指定的位置開始創建n個對象,對象的值均為t的拷貝

uninitialized_copy接受三個迭代器參數。前兩個表示輸入序列,第三個表示這些元素要拷貝到的目的空間。傳遞給uninitialized_copy的目的位置迭代器必須指向未構造的內存返回遞增后的目的位置迭代器,因此,一次uninitialized_copy調用會返回一個指針,指向最后構造的元素之后的位置
uninitialized_fill則更像是填充函數。
這些函數的目標地址都必須足夠大,能容納要創建或拷貝的對象。

示例程序

usealloc.cpp主要展示了allocator的相關用法及使用數組和allocator的區別,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的內存空間的開始string *q = p; //q指向最后構造的元素之后的位置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) //析構上述初始化的stringalloc.destroy(--q); //因為q指向尾后,所以先遞減q,再對其指向的string執行對應的析構函數alloc.deallocate(p, n); //回收之前分配的空間p = alloc.allocate(n); //重新分配n個沒有初始化的的string的內存空間string s; //s用于臨時存儲讀入q = p; //q指向上面分配空間的第一個stringifstream in("data/storyDataFile"); //聲明一個文件輸入流in,讀取目錄下data/storyDataFile的內容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); //析構每一個已初始化的stringalloc.deallocate(p, n); //回收之前分配的空間//使用數組代替上面的實現in.close(); //關閉文件輸入流inin.open("data/storyDataFile"); //重新打開文件輸入流inp = new string[n]; //初始化n個string,構成數組,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[]釋放數組system("pause");return 0; }

運行結果:
創建data/storyDataFile文件:

運行程序,結果如下:

說明in文件讀入流以任意空白作為是否讀取一個string的判斷依據。

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; }

運行結果:

總結

以上是生活随笔為你收集整理的allocator类编程实验的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。