Effective C++学习笔记(8)

目录

  • 条款49:了解new-handler的行为
  • 条款50:了解new和delete的合理替换时机
  • 条款51:编写new和delete时需固守常规
  • 条款52:写了placement new也要写placement delete
  • 条款53:不要轻忽编译器的警告
  • 条款54:让自己熟悉包括TR1在内的标准程序库
  • 条款55:让自己熟悉Boost

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

  • 当operator new抛出异常以反映一个未获满足的内存需求之前,它会先调用一个客户指定的错误处理函数newhandler
  • set_new_handler允许客户指定一个函数,在内存分配无法获得满足时被调用。set_ new_handler 的参数是个指针,指向operator new无法分配足够内存时该被调用的函数。其返回值也是个指针,指向set_new_handler被调用前正在执行(但马上要被输入参数替换)的那个new_handler。
    Effective C++学习笔记(8)_第1张图片
  • Nothrow new是一个颇为局限的工具,因为它只适用于内存分配(保证在operator new内存分配时不跑出异常),但后继的造函数调用还是可能抛出异常
  • 以下模板可为任何类Class添加set_ new_handler支持,只需要Class继承NewHandlerSurpport。在模板类NewHandlerSurpport中,模板参数T其实并未使用,这是为了保证每个继承类拥有各自实体互异的NewHandlerSurpport复件。
    Effective C++学习笔记(8)_第2张图片
    Effective C++学习笔记(8)_第3张图片

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

  • 有许多理由需要写个自定的new和delete,包括改善效能(内存地址对齐原则,处理小块内存问题等等)、对heap运用错误进行调试、收集heap使用信息。

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

  • operator new应该内含一个无穷循环,并在其中尝试分配内存,如果它无法满足内存需求,就该调用new-handler。它也应该有能力处理0 bytes 申请。对象的大小不可能为0 byte,至少为1 byte。
    Effective C++学习笔记(8)_第4张图片

  • Class 专属版本则还应该处理“比正确大小更大的(错误)申请”,例如派生类继承了基类的new操作,通常情况下派生类对象占用内存大小要大于基类对象。
    Effective C++学习笔记(8)_第5张图片

  • operator delete应该在收到null指针时不做任何事。
    Effective C++学习笔记(8)_第6张图片

  • 万一class专属的operator new将大小有误的分配行为转交给标准::operator new执行,你也必须将大小有误的删除行为转交::operator delete 执行。
    Effective C++学习笔记(8)_第7张图片

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

  • 当new一个对象时,第一步调用分配内存的operator new,第二步调用对象类的构造函数。如果第一步调用成功,但在第二步抛出异常,步骤一中的内存分配必须取消并恢复旧观,否则就会造成内存泄漏。在取消内存分配并恢复旧观的过程中,会调用与第一步中new对应的delete操作。正常签名式的new对应正常签名式的delete;placement operator new对应placement operator delete(伴随placement operator new调用而触发构造函数异常时被调用)。如果程序中只有非对应其中各一个,则系统将无法找到调用的函数进行恢复,如下例。
    Effective C++学习笔记(8)_第8张图片

  • 如果要对所有与placement new相关的内存泄漏宣战,我们必须同时提供一个正常的operator delete(用于构造期间无任何异常被抛出)和一个placement版本(用于构造期间有异常被抛出)。后者的额外参数必须和operator new一样。
    Effective C++学习笔记(8)_第9张图片

  • 当你声明placement new和placement delete,请确定不要无意识(非故意)地遮掩了它们的正常版本。缺省情况下C++在global作用域内提供以下形式的operator new:
    在这里插入图片描述
    如果你在class内声明任何operator news,它会遮掩上述这些标准形式。

  • 想要扩展自定义的palcement new and delete,又想避免全局和基类的new delete被掩盖,可建立一个base class,内含所有正常形式的new和delete,凡是想以自定形式扩充标准形式的客户,可利用继承机制及using声明式,如下:
    Effective C++学习笔记(8)_第10张图片
    Effective C++学习笔记(8)_第11张图片

条款53:不要轻忽编译器的警告

  • 严肃对待编译器发出的警告信息。努力在你的编译器的最高(最严苛)警告级别下争取“无任何警告”的荣誉。
  • 不要过度倚赖编译器的报警能力,因为不同的编译器对待事情的态度并不相同。一旦移植到另一个编译器上,你原本倚赖的警告信息有可能消失。

条款54:让自己熟悉包括TR1在内的标准程序库

  • STL库

条款55:让自己熟悉Boost

  • Boost是一个社群,也是一个网站。致力于免费、源码开放、同僚复审的C++程序库开发。Boost 在C++标准化过程中扮演深具影响力的角色。Boost提供许多TR1组件实现品,以及其他许多程序库。
  • https://www.boost.org

你可能感兴趣的:(c++,学习,笔记)