《Effective C++》笔记(一)

   

None.gif Item  1 :  Prefer  const  and inline to  #define .
None.gif
None.gifItem 
2 :  Prefer  < iostream >  to  < stdio.h > .
None.gif
None.gifItem 
3 :   Prefer  new  and delete to malloc and free.
None.gif
None.gifItem 
4 :   Prefer C ++- style comments.
None.gif
None.gifItem 
5 :  Use the same form  in  corresponding uses of  new  and delete.
None.gif
None.gifItem 
6 :  Use delete on pointer members  in  destructors.
None.gif
None.gifItem 
7 :  Be prepared  for   out - of - memory conditions.
None.gif


   当内存分配请求不能满足时,调用你预先指定的一个出错处理函数。这个方法基于一个常规,即当operator new不能满足请求时,会在抛出异常之前调用客户指定的一个出错处理函数——一般称为new-handler函数<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

指定出错处理函数时要用到set_new_handler函数,它在头文件<new>里大致是象下面这样定义的:

None.gif typedef  void  ( * new_handler)();
None.gifnew_handler set_new_handler(new_handler p) 
throw ();
None.gif

可以看到,new_handler是一个自定义的函数指针类型,它指向一个没有输入参数也没有返回值的函数。set_new_handler则是一个输入并返回new_handler类型的函数。

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

可以象下面这样使用set_new_handler

None.gif void  nomorememory()
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif    cerr 
<< "unable to satisfy request for memory\n";
InBlock.gif    abort();
ExpandedBlockEnd.gif}

None.gif
None.gif
int  main()
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif    set_new_handler(nomorememory);
InBlock.gif    
int *pbigdataarray = new int[100000000];    
ExpandedBlockEnd.gif}

None.gif

operator new不能满足内存分配请求时,new-handler函数不只调用一次,而是不断重复,直至找到足够的内存

一个设计得好的new-handler函数必须实现下面功能中的一种。
   
产生更多的可用内存。这将使operator new下一次分配内存的尝试有可能获得成功。实施这一策略的一个方法是:在程序启动时分配一个大的内存块,然后在第一次调用new-handler时释放。释放时伴随着一些对用户的警告信息,如内存数量太少,下次请求可能会失败,除非又有更多的可用空间。
   
安装另一个不同的new-handler函数。如果当前的new-handler函数不能产生更多的可用内存,可能它会知道另一个new-handler函数可以提供更多的资源。这样的话,当前的new-handler可以安装另一个new-handler来取代它(通过调用set_new_handler)。下一次operator new调用new-handler时,会使用最近安装的那个。(这一策略的另一个变通办法是让new-handler可以改变它自己的运行行为,那么下次调用时,它将做不同的事。方法是使new-handler可以修改那些影响它自身行为的静态或全局数据。)
   
卸除new-handler。也就是传递空指针给set_new_handler。没有安装new-handleroperator new分配内存不成功时就会抛出一个标准的std::bad_alloc类型的异常。
   
抛出std::bad_alloc或从std::bad_alloc继承的其他类型的异常。这样的异常不会被operator new捕捉,所以它们会被送到最初进行内存请求的地方。(抛出别的不同类型的异常会违反operator new异常规范。规范中的缺省行为是调用abort,所以new-handler要抛出一个异常时,一定要确信它是从std::bad_alloc继承来的。)
   
没有返回。典型做法是调用abortexit

 

c++不支持专门针对于类的new-handler函数,而且也不需要。你可以自己来实现它,只要在每个类中提供自己版本的set_new_handleroperator new。类的set_new_handler可以为类指定new-handler(就象标准的set_new_handler指定全局new-handler一样)。类的operator new则保证为类的对象分配内存时用类的new-handler取代全局new-handler

None.gif template < class  t >      //  提供类set_new_handler支持的
ExpandedBlockStart.gifContractedBlock.gif
class  newhandlersupport  dot.gif {    // 混合风格”的基类
InBlock.gif
public:
InBlock.gif    
static new_handler set_new_handler(new_handler p);
InBlock.gif    
static void * operator new(size_t size);
InBlock.gif
private:
InBlock.gif    
static new_handler currenthandler;
ExpandedBlockEnd.gif}
;
None.gif
None.giftemplate
< class  t >
None.gifnew_handler newhandlersupport
< t > ::set_new_handler(new_handler p)
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif    new_handler oldhandler 
= currenthandler;
InBlock.gif    currenthandler 
= p;
InBlock.gif    
return oldhandler;
ExpandedBlockEnd.gif}

None.gif
None.giftemplate
< class  t >
None.gif
void   *  newhandlersupport < t > :: operator   new (size_t size)
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif    new_handler globalhandler 
=
InBlock.gif        std::set_new_handler(currenthandler);
InBlock.gif    
void *memory;
ExpandedSubBlockStart.gifContractedSubBlock.gif    
try dot.gif{
InBlock.gif        memory 
= ::operator new(size);
ExpandedSubBlockEnd.gif    }

ExpandedSubBlockStart.gifContractedSubBlock.gif    
catch (std::bad_alloc&dot.gif{
InBlock.gif        std::set_new_handler(globalhandler);
InBlock.gif        
throw;
ExpandedSubBlockEnd.gif    }

InBlock.gif    std::set_new_handler(globalhandler);
InBlock.gif    
return memory;
ExpandedBlockEnd.gif}

None.gif
None.giftemplate
< class  t >
None.gifnew_handler newhandlersupport
< t > ::currenthandler;
None.gif
xset_new_handlerxnewhandlersupport<x>
None.gif class  x:  public  newhandlersupport < x >  
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif
ExpandedBlockEnd.gif}
;        
None.gif

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值