Effective C + + clause 49

Source: Internet
Author: User

Understand the behavior of New-handler

The technique described in this section is to invoke a client-specified error handler before operator new throws an exception: New-handler. How to customize and use this memory exception handling function when memory allocation fails. The key statement is set_new_handler . The author emphasizes how to implement different memory allocation error handlers for class memory allocation.
Let's start with an example from the book and figure out how to use New-handler technology.
The following code:

 void  Outofmem () {std :: cerr  << "Unable        To satisfy request for Memoryn "; std :: abort  ();    //forcibly terminates the process } int  Main () {std :: Set_new_handler (OUTOFMEM)        ; int  *pbigdataarray=new  int        [100000000l ]; return     0 ; }

As in the code, because the call is made, set_new_handler(outOfMem); if the memory allocation fails, it goes to the outofmen function to continue execution. So we have the idea of having different classes of memory allocation problems that can be handled with different functions for each of our own defined classes. For example, Class A has a custom memory handler for Class A, and Class B has a custom memory handler for Class B, in order to implement this function, the author proposes the following implementation methods.

Incidentally, however, the memory processing functions we define have the following characteristics:
1. Allow more memory to be used. This can cause the next memory allocation action within operator new to be successful. One approach is to allocate a large chunk of memory at the beginning of the program and release it when New-handler is first called.
2. Install another new-handler. When the current new-handler cannot get more memory, it may not be until which New-handler has this ability.
3. Remove the New-handler. The null pointer is passed to Set_new_handler, and once no new-handler,operator new is installed, an exception is thrown when the memory allocation is unsuccessful.
4. Throws an exception Bad_alloc (or derived from Bad_alloc). Such exceptions are not captured by operator new and are therefore not propagated to memory demands.
5. Do not return. Usually abort or exit.

  classnewhandlerholder{ Public:ExplicitNewhandlerholder (STD:: New_handler NH): Handlere (NH) {} ~newhandlerholder () {STD:: Set_new_handler (handler); }Private:STD:: New_handler handler; newhandlerholder& (Constnewhandlerholder&);//Prevent copyingnewhandlerholder&operator-(Constnewhandlerholder&); };classwidget{ Public:Static STD:: New_handler Set_new_handler (STD:: New_handler p)Throw();Static void*operator New(STD:: size_t size)Throw(STD:: Bad_alloc);Private:Static STD:: New_handler Currenthandler; };STD:: New_handler widget::currenthandler=0;STD:: New_handler Widget::set_new_handler (STD:: New_handler p)Throw()    {STD:: New_handler Oldhandler=currenthandler;        Currenthandler=p;    REUTRN Oldhandler; }void* Widget::operator New(STD:: size_t size)Throw(STD:: Bad_alloc) {Newhandlerholder h (STD:: Set_new_handler (Currenthandler));//New-handler of the installation widget        return::operator New(size); }voidOutofmem (); Widget::set_new_handler (OUTOFMEM);//Set the new-handling function of Outofmem as widgetwidget* pw1=NewWidgets;//Memory allocation failed, call Outofmem    STD::string* ps=New STD::string;//Memory allocation failure call Global new-handling (if any)Widget::set_new_handler (0);//Set widget exclusive new-handling is nullwidget* pw2=NewWidgets;//Memory allocation failure immediately throws an exception

Let me explain that the above procedure, for the definition class NewHandlerHolder , is to save the memory processing function before the substitution, we can trace the execution of the above code. First, declare one outOfMem() , and then Widget::set_new_handler(outOfMem) set Widget the variables within the statement static std::new_handler currentHandler . Then, new Widget when called, we enter the Widget::operator new(std::size_t size) throw(std::bad_alloc) function body, NewHandlerHolder h(std::set_new_handler(currentHandler)); the statement plays the role of the following, 1. When defining an object, save the NewHandlerHolder pre-replacement memory handler in the variable of the object std::new_handler handler , 2. Set the new new_ for the class widget The handler function. Performs ::operator new(size) a memory allocation and invokes a memory handler that has just been replaced if a memory allocation error occurs. When exiting the body of the function, because NewHandlerHolder of the destructor, the memory processing function is restored without affecting the execution of other memory allocation exceptions.

The above version realizes our requirement function.

However, the author proposes another way to make use of templates:

  classnewhandlerholder{ Public:ExplicitNewhandlerholder (STD:: New_handler NH): Handlere (NH) {} ~newhandlerholder () {STD:: Set_new_handler (handler); }Private:STD:: New_handler handler; newhandlerholder& (Constnewhandlerholder&);//Prevent copyingnewhandlerholder&operator-(Constnewhandlerholder&); };Template<TypeNameT>classnewhandlersupport{ Public:Static STD:: New_handler Set_new_handler (STD:: New_handler p)Throw();Static void*operator New(STD:: size_t size)Throw(STD:: Bad_alloc); ......Private:Static STD:: New_handler Currenthandler; };Template<TypeNameT>STD:: New_handler Newhandlersupport<t>::set_new_handler (STD:: New_handler p)Throw()    {STD:: New_handler Oldhandler=currenthandler; Currenthandler=p;returnOldhandler; }Template<TypeNameT>void* NEWHANDLERSUPPORT&LT;T&GT;::operator New(STD:: size_t size)Throw(STD:: Bad_alloc) {Newhandlerholder h (STD:: Set_new_handler (Currenthandler);return::operator New(size);Template<TypeNameT>STD:: New_handler newhandlersupport<t>::currenthandler=0;classWidgets: Publicnewhandlersupport<widget>{};

This way of implementation for me, temporarily feel awkward, but it reflects the template potential programming value. When we invoke the statement class Widget:public NewHandlerSupport<Widget> , we instantiate a NewHandlerSupport<Widget> class, and our class Widget inherits from that class, so the Widget class inherits the Newhandlersupport function, and the actual program execution process is the same as in the first way. The only difference is that the class widget does not have to redefine static functions about memory processing.

Effective C + + clause 49

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.