Customizing the class of their own new_handler

Source: Internet
Author: User

  the new operator in C + + first allocates space using the operator new function, and then calls the class's constructor in this space to construct the object . When operator new cannot allocate the required memory space, a Bad_alloc exception is thrown by default, and if the user specifies an error handler, New_handler, before the exception is thrown, the program executes the New_handler function for error handling. In order to set this error handler, we need to call the Set_new_handler function, which is within the Std namespace as shown below

namespace std{    void (*new_handler) ();    New_handler Set_new_handler (New_handler p)throw  ();}

The Set_new_handler function does not throw any exceptions. The function takes a New_handler function pointer and returns a pointer like this. Pnew represents that if operator new fails, the error handler used is the function that pnew points to, and the Set_new_handler function returns the previous error handler pointer. Like what

 void   MyErrorHandler () {Cerr  < < "  " ; Abort ();}  int      main () {Std::set_new_handler (MyErrorHandler);  int  *ptr=new  int  [1000000000l   delete   [] ptr;  return  ;}  

  When the memory allocation requirements are not met, the program will constantly call the MyErrorHandler function for memory allocation, if there is no abort () in the error handler, the terminal will continue to print error prompts. Sets the global Set_new_handler, which invokes the error handler whenever a operator new failure occurs. But what if we need to set different error-handling functions for different classes? That means we need to customize the class's own Set_new_handler function.

classwidget{ Public:        StaticStd::new_handler Set_new_handler (Std::new_handler pnew)Throw (); Static void*operator New(std::size_t size)Throw(Std::bad_alloc); Private:        StaticStd::new_handler Currenthandler; intarray[100000000L];//to make it easy for the new widget to appear abnormally};
Std::new_handler widget::currenthandler=0;

As shown above, the class widget needs to define its own new_handler variable, and it needs to define its own Set_new_handler function and operator new function, the Set_new_handler function is relatively simple, referring to the global set_new_ The behavior of the handler function can be.

Std::new_handler Widget::set_new_handler (Std::new_handler pnew) {    std::new_handler oldHandler=  Currenthandler;    Currenthandler=pnew;     return Oldhandler;}

The function Set_new_handler sets the new New_handler and returns the previous New_handler.

So how should the operator new function in the widget class be defined?

  First, it should set the new_handler of this class, how to set its own new_handler and let it work properly? Call Std::set_new_handler, the Currenthandler in the class can be used as its parameter;

  Second, call the Std::operator new function to allocate memory, but there may be a resource leak, as in the first step, we set the global Set_new_handler to the class widget's error handler, and if the allocation fails, How do we set the original New_handler back? One obvious way is to manage new_handler by object, as follows

  

 class   newhandlerholder{ public  :  explicit   Newhandlerholder (New_handler p): Oldhandler (P) {}  ~newhandlerholer () {        Std::set_new_handler (Oldhander);  private  : Std::new_handler Oldhandler        ; Newhandlerholder ( const  newhandlerholder&        ); Newhandlerholder  & operator  = (const  newhandlerholder& 

This is a resource management class, if we define a Newhandlerholder object to manage the original New_handler, when the memory allocation fails, throws an exception and the function is retired, and the destructor of the constructed object is called. When we call Newhandlerholder's destructor, the original new_handler is reset back. The classes used for resource management do not allow assignment and replication constructs in many cases, because we want the resource-managed object to have resource-only management rights.

At this point, we can write out the operator new function in the Widget class.

void* Widget::operatornewthrow  (std::bad_alloc) {    Newhandlerholder Temp (Std::set_new_handler (Currenthandler));     return ::operatornew(size);}

  After defining all the required content, we can use the custom New_handler.

int Main () {    widget::set_new_handler (myerrorhandler);     // Widget::set_new_handler (0);     while (1)         *ptr=new  Widget;}

Running results such as

  

The annotation is unpacked and the result is not "can ' t need the request for memory".

These ideas can be used to write their own custom new_handler for each class, but for each class that needs to write custom New_handler, it seems a bit unreasonable to avoid code duplication, we can use the template

  

Template<typename t>classnewhandlersupport{ Public:        StaticStd::new_handler Set_new_handler (Std::new_handler newhandler)Throw (); Static void*operator New(std::size_t size)Throw(Std::bad_alloc); Private:        StaticStd::new_handler Currenthandler; };template<typename t>void* NEWHANDLERSUPPORT&LT;T&GT;::operator New(std::size_t size) {Newhandlerholder temp (Std::set_new_handler (Currenthandler)); return::operator New(size);} Template<typename t>Std::new_handler Newhandlersupport<t>::set_new_handler (Std::new_handler Newhandler)Throw() {Std::new_handler Oldhander=Currenthandler; Currenthandler=Newhandler; returnOldhandler;} Template<typename t>Std::new_handler Newhandlersupport<t>::currenthandler=0;

  If we want the class widget to get custom new_handler behavior, we just need to inherit the widget class as public newhandlersupport<widget>. We just want to get different static Std::new_handler Currenthandler from different template parameters, and we need to use it to customize the new_handler of each class.

Customizing the class of their own new_handler

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.