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

new失败了会发生什么

当用new来申请一块内存的时候,如果申请失败了,编译器会抛出一个异常(新式)或者返回一个null(旧式)。

在抛出异常或者返回null之前,编译器会先调用一个new_handler的方法,可以理解为错误处理函数。

namespace std {
    typedef void (*new_handler) ();
    new_handler set_new_handler(new_handler p) throw();
}

new_handler是一个函数指针,指向void()函数。在调用new_handler指向的方法前,需要先设置一下,也就是set_new_handler方法。

这个方法参数是个new_handler,返回也是个new_handler。参数指定new失败后调用的那个函数的指针,返回的是原先指定的那个函数的指针。当调用的函数指针是null时,新式new将抛出bad_alloc异常。

自己写一个new_handler

class专属new_handler。一个类想自己写一个new_handler需要干两件事

  • 写set_new_handler:让用户指定类专属new_handler
  • 写operator new:让编译器用类专属new_handler替换global_new_handler(默认的)

举个例子,加我们有Widget类,我们想给这个类设计一个new_handler。

class Widget {
 public:
  static std::new_handler set_new_handler(std::new_handler p) throw();
  static void* operator new(std::size_t size) noexcept(false);
 private:
  static std::new_handler currentHandler;
};
std::new_handler Widget::currentHandler = nullptr;

set_new_handler要干的事。

std::new_handler Widget::set_new_handler(std::new_handler p) throw() {
  std::new_handler oldHandler = currentHandler;	// 保存旧的new_handler
  currentHandler = p;							// 用新的替换旧的
  return oldHandler;							// 返回旧的
}

这里文字叙述一下operator new要干的事

  • 调用标准的set_new_handler:将new_hander设置为global_new_handler(默认的)
  • 调用标准的global operator new:实际分配内存
  • 如果分配内存出错了,就调用自己的new_handler。如果还是不行抛出bad_alloc异常。
  • 如果分配内存没错,那就直接返回一个指针。

后面的内容感觉有点跟不上时代了,就不总结了。

上一篇:剑指Offer 49.丑数


下一篇:系统集成项目管理工程师-模拟测试2-49分