CSDN首页 空间 新闻 论坛 Blog 下载 读书 网摘 搜索 .NET Java 视频 接项目 求职 在线学习 买书 程序员 通知
不看会后悔的Windows XP之经验谈 简单快捷DIY实用家庭影院
CSDN社区
搜索 收藏 打印 关闭
CSDN社区 >  C/C++ >  C++ 语言

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

楼主fatalerror99(iTePub's Nirvana)2005-04-07 17:04:24 在 C/C++ / C++ 语言 提问

在这篇文章中,作者提供了一个模板类   NewHandlerSupport   的实现,其中定义并实现了成员函数   set_new_handler(),但是似乎并没有用到,只用到了   std::set_new_handler()。  
   
  我在我的测试程序中注释掉这个成员函数的定义和实现,程序照样可以编译并运行。  
  我在程序中   set_new_handler()   的实现的最前面加入一条输出语句。然后让程序在无限循环中不断调用重载的   new   运算符,但是直到抛出异常,也没有执行到我的那条输出语句。  
   
  既然没有用到,那么在模板类中实现   set_new_handler()   有什么用呢?  
   
  希望看过这篇文章的高手能解答我的疑问。 问题点数:60、回复次数:8Top

1 楼fatalerror99(iTePub's Nirvana)回复于 2005-04-07 17:33:26 得分 0

还有,如果我把重载的   new   中的   std::set_new_handler()   都换成   NewHandlerSupport::set_new_handler()   是不是可以呢?我试了一下,没发现有什么问题,作者为什么定义了   NewHandlerSupport::set_new_handler(),而在可以用的时候却又去用   std::set_new_handler()   呢?Top

2 楼thomasnew(重新得到)回复于 2005-04-07 18:25:04 得分 60

文章说的很清楚啊,对照下面几句话:(全是原话,我看的是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;  
  }  
   
  ---------------------Top

3 楼fatalerror99(iTePub's Nirvana)回复于 2005-04-07 18:40:22 得分 0

就是说,new不成功时,你安装的new   hander是自动被调用的。  
   
  这个恐怕不对吧,所谓的“即当operator   new不能满足请求时,会在抛出异常之前调用客户指定的一个出错处理函数——一般称为new-handler函数”,是因为在   std::new   的实现中调用了这个函数,如果你重载   new   的话,必须在重载的实现中显式调用。  
   
  你引用的这段我只仔细看过的,但我的疑问也正是来自于这一段,他定义了自己的   set_new_handler   函数,为什么不去使用,却使用标准的   std::set_new_handler()   。Top

4 楼fatalerror99(iTePub's Nirvana)回复于 2005-04-07 18:47:10 得分 0

还有,我说过我在   NewHandlerSupport::set_new_handler()   中加了一条输出语句,却直到抛出异常也没有执行到,说明根本就没有调用到   NewHandlerSupport::set_new_handler()。因为重载的   new   中调用的都是   std::set_new_handler()   。Top

5 楼thomasnew(重新得到)回复于 2005-04-07 18:48:01 得分 0

new   中做的是设置好那个要被自动调用的函数,但并不是在new中调用的,  
  你要安装自己的new   hander,就要重载new,用来安装自己的new   handerTop

6 楼thomasnew(重新得到)回复于 2005-04-07 19:01:02 得分 0

我说过我在   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;  
  }  
   
   
  Top

7 楼thomasnew(重新得到)回复于 2005-04-07 19:05:37 得分 0

你要安装自己的new   hander,就要重载new,用来安装自己的new   hander  
  ------  
  这句有问题,呵呵,sorry。  
  x的set_new_hander   和标准的set_new_hander(我们看到的)功能一样,所以用哪个都可以Top

8 楼fatalerror99(iTePub's Nirvana)回复于 2005-04-07 22:15:50 得分 0

既然X的set_new_hander   和标准的set_new_hander(我们看到的)功能一样,那为什么还要自己写一个set_new_hander   呢?一直用标准的不也可以嘛。Top

相关问题

  • 在Dev-C++重载运算符问题
  • 重载运算符
  • 关于C++中运算符重载的问题
  • Delphi能象C++一样重载运算符吗?
  • String的+是不是像c++一样重载运算符?
  • 关于C++运算符重载的问题????
  • c++运算符重载问题,调试出错
  • C++运算符重载的一个问题
  • C++运算符重载的一个问题
  • 关于C++中类的运算符重载的问题

关键词

  • c++
  • 函数
  • 安装
  • 指针
  • 内存
  • 语句
  • 模板
  • 代码
  • 执行
  • 调用

得分解答快速导航

  • 帖主:fatalerror99
  • thomasnew

相关链接

  • C/C++ Blog
  • C/C++类图书
  • C/C++类源码下载

广告也精彩

反馈

请通过下述方式给我们反馈
反馈
提问
网站简介|广告服务|VIP资费标准|银行汇款帐号|网站地图|帮助|联系方式|诚聘英才|English|问题报告
北京创新乐知广告有限公司 版权所有, 京 ICP 证 070598 号
世纪乐知(北京)网络技术有限公司 提供技术支持
Copyright © 2000-2008, CSDN.NET, All Rights Reserved
GongshangLogo