德國TOPEX 7054-12-300 德國TOPEX 7054-12-300
ACTARIS R133-5-72 DN25 PN5 減壓閥
AVS-ROMER XGV-2000-000D12PP-04 腰鼓閥
BAUMER HEAG150-H-1H-2R-3T
BILZ ARTIKEL-NR.11-0017 BNRS70/0# + ARTIKEL-NR.19-0192 M20X250/2#
BONESI S1A/2 氣閥
BONESI S1A/34 氣閥
BONFIGLIOLI HL14112EH002 , NFF 14 112 EH B5 B5 電磁離合器
DEMAG 77330044 操作手柄
DEMAG 71881033 控制電纜
DIECKERS 7280650 DN 6,35 傳感器
FHF BERGBAUTECHNIK FHF12363001AX
G.BEE STV200072230 AKP87E-1/2-DAE42N-GROB 球閥
GEMU 88246965 554 15D 137 52 0 截止閥
JVL MAC140-A1AAAA-A009 伺服電機
OPTEK DTF16 1426-3151-1001-01 光源燈
OPTEK 新的貨號: AF16, 1426-3131-0801-03
OPTEK AF16, 1426-3131-0801-03 光源燈
PILUCY PE-203 定量閥
PILZ 751110 繼電器
PILZ 774100
PILZ 751107
PILZ 751105
PILZ 751104
PILZ 751111
REPACK-S CPR02-1000-P32-F 密封
REPACK-S CPR02-0800-P32-F 密封
REPACK-S CPR02-0700-P32-F 密封
REPACK-S CPR02-0900-P32-F 密封
REPACK-S HRX-065001-P905F 密封
REPACK-S CPR01-0650-P41-F 密封
RITTAL SK 3302100 空調
SCHLICK ITEM 44513, 970/7-1 S 75 VERSION 1.0, D 4.1051/1
SCHURTER 7010.3480 240個起訂, 10個一包裝
SPM SPM VMM-15 震動傳感器
UMWELTSENSORTECHNIK VGT1-110172003 手持式氣體檢漏儀
定義自定義分配器的主要原因之一是提升性能。利用的自定義分配器可以提高程序的性能,又或提高內存使用效率,亦或兩者兼而有之。默認分配器使用new操作符分配存儲空間,而這常利用C語言堆分配函數(malloc())實現。由于堆分配函數常針對偶發的內存大量分配作優化,因此在為需要一次分配大量內存的容器(如矢量、雙端隊列)分配內存時,默認分配器一般效率良好。但是,對于映射表與雙向鏈表這類需要頻繁分配少量內存的容器來說,若采用默認分配器分配內存,則通常效率很低。除此之外,基于malloc()的默認分配器還存在許多問題,諸如較差的引用局部性,以及可能造成內存碎片化。
有鑒于此,在這一情況下,人們常使用基于內存池的分配器來解決頻繁少量分配問題。與默認的"按需分配"方式不同,在使用基于內存池的分配器時,程序會預先為之分配大塊內存(即"內存池"),而后在需要分配內存時,自定義分配器只需向請求方返回一個指向池內內存的指針即可;而在對象析構時,并不需實際解除分配內存,而是延遲到內存池的生命周期完結時才真正解除分配。
在"自定義分配器"這一話題上,已有諸多C++專家與相關作者參與探討,例如斯科特·梅耶斯的作品《Effective STL》與安德烈·亞歷山德雷斯庫的《Modern C++ Design》都有提及。梅耶斯洞察到,若要求某一分配器的所有實例等效,則可移植的分配器必須不包含狀態。雖然C++標準鼓勵庫的實現者支持帶狀態的分配器,但梅耶斯稱,相關段落是"(看似)美妙的觀點",但也幾乎是空話,并稱分配器的限制"過于嚴苛"。
另外,在《C++程序設計語言》中,比雅尼·斯特勞斯特魯普則認為"'嚴格限制分配器,以免各對象信息不同',這點顯然問題不大"(大意),并指出大部分分配器并不需要狀態,甚至沒有狀態時性能反倒更佳。他提出了三個自定義分配器的用例:內存池型的分配器、共享內存型分配器與垃圾回收型分配器,并展示了一個分配器的實現,此間利用了一個內部內存池,以快速分配/解除分配少量內存。但他也提到,如此優化可能已經在他所提供的樣例分配器中實現。
自定義分配器的另一用途是調試內存相關錯誤。若要做到這一點,可以編寫一個分配器,令之在分配時分配額外的內存,并借此存放調試信息。這類分配器不僅可以保證內存由同類分配器分配/解除分配內存,還可在一定程度上保護程序免受緩存溢出之害。
折疊使用方法
當初始化標準容器時,若需使用自定分配器,則可將其寫入模板參數,以代替默認的std::allocator<T>,如下所示:
namespace std { template <class T, class Allocator = allocator<T> > class vector;// ...
正如其他所有C++類模板般,在初始化同一標準庫容器時,若使用了不同的分配器,則所生成容器的類型亦不同。譬如,若函數需一整型矢量數組std::vector<int>作為參數,則其只能接受由默認分配器生成的整型矢量數組。
折疊C++11
通過加入"作用域"分配器,C++11標準進一步強化了分配器接口,從而保證帶有嵌套式內存分配特點的容器(如字符串矢量數組等)所分配到的內存皆來自容器自身的分配器。
另外,C++11標準刪除了"給定類型的分配器在比較時總是相等"的模棱兩可的要求,使帶狀態分配器不僅實用性得到提升,而且可管理進程外的共享內存。現今分配器的作用多為讓程序員可以控制容器的內存分配,而非適應基底硬件的地址模型。事實上,C++11標準刪去了分配器"自適應地址模型"的功能,結果抹消了其設計初衷。