CUJ:标准库:Allocator能做什么?[1]

[入库:2005年8月18日] [更新:2007年3月24日]

本文简介:选择自 taodm 的 blog

the standard librarian: what are allocators good for?

matt austern

http://www.cuj.com/experts/1812/austern.htm?topic=experts

--------------------------------------------------------------------------------

allocatorc++语言标准库中最神秘的部分之一。它们很少被显式使用,标准也没有明确出它们应该在什么时候被使用。今天的allocator与最初的stl建议非常不同,在此过程中还存在着另外两个设计--这两个都依赖于语言的一些特性,而直到最近才在很少的几个编译器上可用。对allocator的功能,标准似乎在一些方面追加了承诺,而在另外一些方面撤销了承诺。

    这篇专栏文章将讨论你能用allocator来做什么以及如何定义一个自己的版本。我只会讨论c++标准所定义的allocator:引入准标准时代的设计,或试图绕过有缺陷的编译器,只会增加混乱。

什么时候不使用allocator

    c++标准中的allocator分成两块:一个通用需求集(描述于§ 20.1.5(表 32)),和叫std::allocator的class(描述于§20.4.1)。如果一个class满足表32的需求,我们就称它为一个allocator。std::allocator类满足那些需求,因此它是一个allocator。它是标准程序库中的唯一一个预先定义allocator类。

    每个 c++程序员都已经知道动态内存分配:写下new x来分配内存和创建一个x类型的新对象,写下delete p来销毁p所指的对象并归还其内存。你有理由认为allocator会使用new和delete--但它们没有。(c++标准将::operator new()描述为“allocation function”,但很奇怪,allocator并不是这样的。)

    有关allocator的最重要的事实是它们只是为了一个目的:封装stl容器在内存管理上的低层细节。你不应该在自己的代码中直接调用allocator的成员函数,除非正在写一个自己的stl容器。你不应该试图使用allocator来实现operator new[];这不是allocator该做的。 如果你不确定是否需要使用allocator,那就不要用。

    allocator是一个类,有着叫allocate()和deallocate()成员函数(相当于malloc和free)。它还有用于维护所分配的内存的辅助函数和指示如何使用这些内存的typedef(指针或引用类型的名字)。如果一个stl容器使用用户提供的allocator来分配它所需的所有内存(预定义的stl容器全都能这么做;他们都有一个模板参数,其默认值是std::allocator),你就能通过提供自己的allocator来控制它的内存管理。

    这种柔性是有限制的:仍然由容器自己决定它将要申请多少内存以及如何使用它们。在容器申请更多的内存时,你能控制它调用那个低层函数,但是你不能通过使用allocator来让一个vector行动起来像一个deque一样。虽然如此,有时候,这个受限的柔性也很有用。比如,假设你有一个特殊的fast_allocator,能快速分配和释放内存(也许通过放弃线程安全性,或使用一个小的局部堆),你能通过写下std::list<t, fast_allocator<t> >而不是简单的std::list<t>来让标准的list使用它。

    如果这看起来对你很陌生,那就对了。没有理由在常规代码中使用allocator的。

定义一个allocator

    关于allocator的这一点你已经看到了:它们是模板。allocator,和容器一样,有value_type,而且allocator的value_type必须要匹配于使用它的容器的value_type。这有时会比较丑陋:map的value_type相当复杂,所以显式调用allocator的map看起来象这样的,std::map<k,v, fast_allocator<std::pair<const k, v> > >。(像往常一样,typedef会对此有帮助。)

本文关键:CUJ、allocator、STL、Matt Austern
 

本站最佳浏览方式为 分辨率 1024x768 IE 6.0(或更高版本的 IE浏览器)

go top