您的位置:首页 > 编程语言 > C语言/C++

effective C++读书笔记八 —— 定制new 和delete

2010-12-12 17:08 260 查看

条款49:了解 new-handler的行为

(1)设计良好的new-handler函数必须做以下事情:
l 让更多内存可被使用。刚开始分配一大块内存,而后当new-handler第一次被调用,将它们释放还给程序使用。
l 安装另一个new-handler
l 卸除new-handler。将null传给set_new_handler,一旦没有安装任何new_handler, operator new 会在内存分配不成功时抛出异常。
l 抛出bad_alloc的异常,这样的异常不会被operator new捕获,会被传播到内存索求处。
l 不返回。通常调用abort或exit。
(2)set_new_handler允许客户指定一个函数,在内存分配无法获得满足时被调用。
(3)Nothrow new是一个颇为局限的工具,因为它只适用于内存分配;后继的构造函数调用还是可能抛出异常。使用nothrow new只能保证operator new不抛异常,不保证像“new (std::nothrow) Widget”这样的表达式绝不导致异常。因此你其实没有运用nothrow new的需要。

47. 条款50:了解 new和delete的合理替换时机

(1)用来检测运用上的错误。如果operator new持有一串动态分配所得地址,而operator delete将地址从中移走,可以容易检测出错误。各种编程错误可能导致数据“overruns”(写入点在分配区块尾端之后)或“underruns”(写入点在分配区块起点之前)。自行定义operator news和deletes检查放置特定的byte patterns(签名)是否原封不动。
(2)为了强化效能。编译器所带的主要用于一般目的,必须处理一系列的需求,包括大块内存、小块内存和各种分配形态,定制版本的new和delete能大幅提升效能。
(3)为了收集使用上的统计数据。自行定义operator new和operator delete,可以轻松收集软件如何使用动态内存,分配区块大小等。
(4)为了增加分配和归还速度。
(5)为了降低缺省内存管理器带来的空间额外开销。泛型内存管理器不只比定制型慢,还使用更多的内存,因为常常在每个分配区上招引某些额外的开销。
(6)为了弥补缺省分配器中的非最佳齐位。编译器自带的operator new并不保证对动态分配而得到的采用相应的齐位方式。
(7)为了将相关对象成簇集中。如果某个特定的数据结构往往一起使用,在处理这些数据时将“内存页错误”的频率降至最低,它们就可以被成簇集中在尽可能少的内存页上。
(8)为了获得非传统行为。比如你可能会希望分配和归还共享内存内的区块。

48.条款51:编写new和delete时需固守常规

(1)operator new应该内含一个无穷循环,并在其中尝试分配内存,如果它无法满足内存需求,就该调用new-handler,它也应该有能力处理0 bytes申请。Class专属版本则还应该处理“比正确大小更大的(错误)申请”。
(2)如果当Base class专属的operator new并非被设计用来进行base class的operator new被用来分配derived 对象,最佳做法是将“内存申请量错误”的调用行为改为采用标准operator new。
(3)如果你打算控制class专属的“array内存分配行为”,需要是实现operator new的array兄弟版本:operator new[]。如果你决定写个operator new[],唯一需要做的一件事就是分配一块未加工内存。因为你不知道每个对象多大,多少个元素,base class的operator new[] 有可能经由继承调用。
(4)operator delete应该在收到null指针时不做任何事情,class专属版本则还应该处理“比正确大小更大的申请”。

49.条款52:写了placement new也要写placement delete

(1)当你写一个placement operator new,请确定也写出了对应的placement operator delete,如果没有这样做,你的程序可能会发生隐微而时断时续的内存泄露。
(2)当你声明placement new和placement delete,请确定不要无意识地遮掩了它们的正常版本。
(3)如果placement new中定义了额外的参数时,运行期刺痛寻找“参数个数和类型都与operator new相同”的operator delete。如果一个带额外参数的operator new没有“带相同额外参数”的对应版operator delete,那么当new的内存分配动作需要取消并恢复旧观时就没有任何operator delete调用。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: