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

来源:互联网 发布:网络实时课堂 编辑:程序博客网 时间:2024/05/29 10:53

条款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  不返回。通常调用abortexit

2set_new_handler允许客户指定一个函数,在内存分配无法获得满足时被调用。

3Nothrow new是一个颇为局限的工具,因为它只适用于内存分配;后继的构造函数调用还是可能抛出异常。使用nothrow new只能保证operator new不抛异常,不保证像“new std::nothrow Widget”这样的表达式绝不导致异常。因此你其实没有运用nothrow new的需要。

47. 条款50:了解 newdelete的合理替换时机

1)用来检测运用上的错误。如果operator new持有一串动态分配所得地址,而operator delete将地址从中移走,可以容易检测出错误。各种编程错误可能导致数据“overruns”(写入点在分配区块尾端之后)或“underruns”(写入点在分配区块起点之前)。自行定义operator newsdeletes检查放置特定的byte patterns(签名)是否原封不动。

2)为了强化效能。编译器所带的主要用于一般目的,必须处理一系列的需求,包括大块内存、小块内存和各种分配形态,定制版本的newdelete能大幅提升效能。

3)为了收集使用上的统计数据。自行定义operator newoperator delete,可以轻松收集软件如何使用动态内存,分配区块大小等。

4)为了增加分配和归还速度。

5)为了降低缺省内存管理器带来的空间额外开销。泛型内存管理器不只比定制型慢,还使用更多的内存,因为常常在每个分配区上招引某些额外的开销。

6)为了弥补缺省分配器中的非最佳齐位。编译器自带的operator new并不保证对动态分配而得到的采用相应的齐位方式。

7)为了将相关对象成簇集中。如果某个特定的数据结构往往一起使用,在处理这些数据时将“内存页错误”的频率降至最低,它们就可以被成簇集中在尽可能少的内存页上。

8)为了获得非传统行为。比如你可能会希望分配和归还共享内存内的区块。

48.条款51:编写newdelete时需固守常规

1operator new应该内含一个无穷循环,并在其中尝试分配内存,如果它无法满足内存需求,就该调用new-handler,它也应该有能力处理0 bytes申请。Class专属版本则还应该处理“比正确大小更大的(错误)申请”。

2)如果当Base class专属的operator new并非被设计用来进行base classoperator new被用来分配derived 对象,最佳做法是将“内存申请量错误”的调用行为改为采用标准operator new

3)如果你打算控制class专属的“array内存分配行为”,需要是实现operator newarray兄弟版本:operator new[]。如果你决定写个operator new[],唯一需要做的一件事就是分配一块未加工内存。因为你不知道每个对象多大,多少个元素,base classoperator new[] 有可能经由继承调用。

4operator delete应该在收到null指针时不做任何事情,class专属版本则还应该处理“比正确大小更大的申请”。

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

1)当你写一个placement operator new,请确定也写出了对应的placement operator delete,如果没有这样做,你的程序可能会发生隐微而时断时续的内存泄露。

2)当你声明placement newplacement delete,请确定不要无意识地遮掩了它们的正常版本。

3)如果placement new中定义了额外的参数时,运行期刺痛寻找“参数个数和类型都与operator new相同”的operator delete。如果一个带额外参数的operator new没有“带相同额外参数”的对应版operator delete,那么当new的内存分配动作需要取消并恢复旧观时就没有任何operator delete调用。

原创粉丝点击