《Effective C++》知识点(8)--定制new和delete

49. 了解new-handler的行为

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

    49.2 一个设计良好的new-handler函数必须:

           a.  让更多内存可被使用(程序一开始分配一大块内存)。

           b. 安装另一个new-handler。做法之一是令new-handler修改"会影响new-handler行为"的

               static数据、namespace数据或global数据。

           c. 卸除new-handler。将null指针传给set_new_handler,内存分配不成功时抛出异常。

           d. 抛出bad_alloc(或派生自bad_alloc)的异常(不被operator new捕捉)。

           e. 不返回。通常调用abort或exit。

    49.3 Nothrow new是一个颇为局限的工具,因为它只适用于内存分配,后继的构造函数调用还

            是可能抛出异常。  

    49.4 CRTP(curiously recurring template pattern)奇异递归模板模式

            一个类X继承自一个模板化的基类A,而A 又以X作为类型参数。CRTP可以被用于实现编译

            期多态(静态多态),其中基类A用来定义(暴露)接口,派生类X用来实现这些接口。

50. 了解new和delete的合理替换时机

      为什么会需要替换编译器提供的operator new或operator delete?

         a. 用来检测运用上的错误。数据"overruns"(写入点在分配区块尾端之后)或"underruns"(写入

             点在分配区块起点之前)。自定义new可以超额分配内存,以额外的空间放置特定的byte

             patterns(即签名signatures)。自定义delete则可以检查签名是否正确,若否则表示在分配

             区的某个时间点发生了overrun或underrun,此时可以log事件。

         b. 为了收集使用上的统计数据。

         c. 为了增加分配和归还的速度(强化效能)。定制版的new和delete比缺省版本更快。

         d. 为了降低缺省内存管理器带来的空间额外开销(强化效能)。定制版的new和delete比缺省版

             本更省空间。   

         e. 为了弥补缺省分配器中的非最佳齐位。如new时保证8-byte齐位。

          f. 为了将相关对象成簇集中。构建单独的heap,将数据集中在尽可能少的内存页。

         g. 为了获得非传统的行为。如包装C API,delete时擦除内容等。

51. 编写new和delete时需固守常规

    51.1 自定义operator new

         a. 应该内含一个无穷循环,并在其中尝试分配内存,如果它无法满足内存需求,就应该调用

              new-handler。

         b. 应该有能力处理0 byte申请(视为1 byte申请)。

         c. 类的专属版本应该能处理"与正确大小不一致的(错误)"申请(交给标准operator new)。

    51.2 自定义operator delete

         a. 应该在收到null指针时不做任何事。

         b. 类的专属版本应该能处理"与正确大小不一致的(错误)"申请(交给标准operator delete)。

52. 写了placement new也要写placement delete

     如果operator new接受的参数除了一定会有的size_t之外还有其它,这就是placement new。

    52.1 当你写了一个placement new,确保也写了对应的placement delete。如果没有这样做,你的程序可能会发生隐藏的内存泄漏。

    52.2 当你声明placement new和placement delete,请确保没有掩盖它们的正常版本(条款33)。

          缺省情况下,global作用域的operator new:

          a. void* operator new(std::size_t) throw(std::bad_alloc); //normal new

          b. void* operator new(std::size_t,void*) throw(); //placement new

          c. void* operator new(std::size_t,const std::nothrow_t&) throw();//placement new

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值