关于 Effective C++ 的 Item 7 中重载 new 运算符的问题

fatalerror99 2005-04-07 05:04:24
在这篇文章中,作者提供了一个模板类 NewHandlerSupport 的实现,其中定义并实现了成员函数 set_new_handler(),但是似乎并没有用到,只用到了 std::set_new_handler()。

我在我的测试程序中注释掉这个成员函数的定义和实现,程序照样可以编译并运行。
我在程序中 set_new_handler() 的实现的最前面加入一条输出语句。然后让程序在无限循环中不断调用重载的 new 运算符,但是直到抛出异常,也没有执行到我的那条输出语句。

既然没有用到,那么在模板类中实现 set_new_handler() 有什么用呢?

希望看过这篇文章的高手能解答我的疑问。
...全文
190 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
fatalerror99 2005-04-07
  • 打赏
  • 举报
回复
既然X的set_new_hander 和标准的set_new_hander(我们看到的)功能一样,那为什么还要自己写一个set_new_hander 呢?一直用标准的不也可以嘛。
thomasnew 2005-04-07
  • 打赏
  • 举报
回复
你要安装自己的new hander,就要重载new,用来安装自己的new hander
------
这句有问题,呵呵,sorry。
x的set_new_hander 和标准的set_new_hander(我们看到的)功能一样,所以用哪个都可以
thomasnew 2005-04-07
  • 打赏
  • 举报
回复
我说过我在 NewHandlerSupport::set_new_handler() 中加了一条输出语句,却直到抛出异常也没有执行到.说明根本就没有调用到 NewHandlerSupport::set_new_handler()。因为重载的 new 中调用的都是 std::set_new_handler() 。
----------------------------
只是说明,没有用你的set_new_hander()来安装new hander,原因你自己说出来了,“因为重载的 new 中调用的都是 std::set_new_handler() ”

再看看这段话:
"类x中的set_new_handler函数会保存传给它的任何指针,并返回在调用它之前所保存的任何指针。这正是标准版本的set_new_handler所做的:
new_handler x::set_new_handler(new_handler p)
{
new_handler oldhandler = currenthandler;
currenthandler = p;
return oldhandler;
}


thomasnew 2005-04-07
  • 打赏
  • 举报
回复
new 中做的是设置好那个要被自动调用的函数,但并不是在new中调用的,
你要安装自己的new hander,就要重载new,用来安装自己的new hander
fatalerror99 2005-04-07
  • 打赏
  • 举报
回复
还有,我说过我在 NewHandlerSupport::set_new_handler() 中加了一条输出语句,却直到抛出异常也没有执行到,说明根本就没有调用到 NewHandlerSupport::set_new_handler()。因为重载的 new 中调用的都是 std::set_new_handler() 。
fatalerror99 2005-04-07
  • 打赏
  • 举报
回复
就是说,new不成功时,你安装的new hander是自动被调用的。

这个恐怕不对吧,所谓的“即当operator new不能满足请求时,会在抛出异常之前调用客户指定的一个出错处理函数——一般称为new-handler函数”,是因为在 std::new 的实现中调用了这个函数,如果你重载 new 的话,必须在重载的实现中显式调用。

你引用的这段我只仔细看过的,但我的疑问也正是来自于这一段,他定义了自己的 set_new_handler 函数,为什么不去使用,却使用标准的 std::set_new_handler() 。
thomasnew 2005-04-07
  • 打赏
  • 举报
回复
文章说的很清楚啊,对照下面几句话:(全是原话,我看的是lostmouse翻译的)

“这个方法基于一个常规,即当operator new不能满足请求时,会在抛出异常之前调用客户指定的一个出错处理函数——一般称为new-handler函数。(operator new实际工作起来要复杂一些,详见条款8)

---
::就是说,new不成功时,你安装的new hander是自动被调用的。

“set_new_handler的输入参数是operator new分配内存失败时要调用的出错处理函数的指针,返回值是set_new_handler没调用之前就已经在起作用的旧的出错处理函数的指针。”
---
::这个就记住吧

下面这些说明,很明白啊,说明加代码,代码中还有注释,模板只是把不相干的类型换成了T,看x类的实现就好理解了

---------------------
最后看看x的operator new所做的:
1. 调用标准set_new_handler函数,输入参数为x的出错处理函数。这使得x的new-handler函数成为全局new-handler函数。注意下面的代码中,用了"::"符号显式地引用std空间(标准set_new_handler函数就存在于std空间)。

2. 调用全局operator new分配内存。如果第一次分配失败,全局operator new会调用x的new-handler,因为它刚刚(见1.)被安装成为全局new-handler。如果全局operator new最终未能分配到内存,它抛出std::bad_alloc异常,x的operator new会捕捉到它。x的operator new然后恢复最初被取代的全局new-handler函数,最后以抛出异常返回。

3. 假设全局operator new为类型x的对象分配内存成功,, x的operator new会再次调用标准set_new_handler来恢复最初的全局出错处理函数。最后返回分配成功的内存的指针。
c++是这么做的:


void * x::operator new(size_t size)
{
new_handler globalhandler = // 安装x的new_handler
std::set_new_handler(currenthandler);

void *memory;

try { // 尝试分配内存
memory = ::operator new(size);
}

catch (std::bad_alloc&) { // 恢复旧的new_handler
std::set_new_handler(globalhandler);
throw; // 抛出异常
}
std::set_new_handler(globalhandler); // 恢复旧的new_handler
return memory;
}

---------------------
fatalerror99 2005-04-07
  • 打赏
  • 举报
回复
还有,如果我把重载的 new 中的 std::set_new_handler() 都换成 NewHandlerSupport::set_new_handler() 是不是可以呢?我试了一下,没发现有什么问题,作者为什么定义了 NewHandlerSupport::set_new_handler(),而在可以用的时候却又去用 std::set_new_handler() 呢?

64,648

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧